/*eslint-disable block-scoped-var, id-length, no-control-regex, no-magic-numbers, no-prototype-builtins, no-redeclare, no-shadow, no-var, sort-vars*/
import * as $protobuf from "protobufjs/minimal";

// Common aliases
const $Reader = $protobuf.Reader, $Writer = $protobuf.Writer, $util = $protobuf.util;

// Exported root namespace
const $root = $protobuf.roots["default"] || ($protobuf.roots["default"] = {});

export const hbb = $root.hbb = (() => {

    /**
     * Namespace hbb.
     * @exports hbb
     * @namespace
     */
    const hbb = {};

    hbb.RegisterPeer = (function() {

        /**
         * Properties of a RegisterPeer.
         * @memberof hbb
         * @interface IRegisterPeer
         * @property {string|null} [id] RegisterPeer id
         * @property {number|null} [serial] RegisterPeer serial
         */

        /**
         * Constructs a new RegisterPeer.
         * @memberof hbb
         * @classdesc Represents a RegisterPeer.
         * @implements IRegisterPeer
         * @constructor
         * @param {hbb.IRegisterPeer=} [properties] Properties to set
         */
        function RegisterPeer(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * RegisterPeer id.
         * @member {string} id
         * @memberof hbb.RegisterPeer
         * @instance
         */
        RegisterPeer.prototype.id = "";

        /**
         * RegisterPeer serial.
         * @member {number} serial
         * @memberof hbb.RegisterPeer
         * @instance
         */
        RegisterPeer.prototype.serial = 0;

        /**
         * Creates a new RegisterPeer instance using the specified properties.
         * @function create
         * @memberof hbb.RegisterPeer
         * @static
         * @param {hbb.IRegisterPeer=} [properties] Properties to set
         * @returns {hbb.RegisterPeer} RegisterPeer instance
         */
        RegisterPeer.create = function create(properties) {
            return new RegisterPeer(properties);
        };

        /**
         * Encodes the specified RegisterPeer message. Does not implicitly {@link hbb.RegisterPeer.verify|verify} messages.
         * @function encode
         * @memberof hbb.RegisterPeer
         * @static
         * @param {hbb.IRegisterPeer} message RegisterPeer message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        RegisterPeer.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.id != null && Object.hasOwnProperty.call(message, "id"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.id);
            if (message.serial != null && Object.hasOwnProperty.call(message, "serial"))
                writer.uint32(/* id 2, wireType 0 =*/16).int32(message.serial);
            return writer;
        };

        /**
         * Encodes the specified RegisterPeer message, length delimited. Does not implicitly {@link hbb.RegisterPeer.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.RegisterPeer
         * @static
         * @param {hbb.IRegisterPeer} message RegisterPeer message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        RegisterPeer.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a RegisterPeer message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.RegisterPeer
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.RegisterPeer} RegisterPeer
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        RegisterPeer.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.RegisterPeer();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.id = reader.string();
                        break;
                    }
                case 2: {
                        message.serial = reader.int32();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a RegisterPeer message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.RegisterPeer
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.RegisterPeer} RegisterPeer
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        RegisterPeer.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a RegisterPeer message.
         * @function verify
         * @memberof hbb.RegisterPeer
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        RegisterPeer.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.id != null && message.hasOwnProperty("id"))
                if (!$util.isString(message.id))
                    return "id: string expected";
            if (message.serial != null && message.hasOwnProperty("serial"))
                if (!$util.isInteger(message.serial))
                    return "serial: integer expected";
            return null;
        };

        /**
         * Creates a RegisterPeer message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.RegisterPeer
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.RegisterPeer} RegisterPeer
         */
        RegisterPeer.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.RegisterPeer)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.RegisterPeer();
            if (object.id != null)
                message.id = String(object.id);
            if (object.serial != null)
                message.serial = object.serial | 0;
            return message;
        };

        /**
         * Creates a plain object from a RegisterPeer message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.RegisterPeer
         * @static
         * @param {hbb.RegisterPeer} message RegisterPeer
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        RegisterPeer.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.id = "";
                object.serial = 0;
            }
            if (message.id != null && message.hasOwnProperty("id"))
                object.id = message.id;
            if (message.serial != null && message.hasOwnProperty("serial"))
                object.serial = message.serial;
            return object;
        };

        /**
         * Converts this RegisterPeer to JSON.
         * @function toJSON
         * @memberof hbb.RegisterPeer
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        RegisterPeer.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for RegisterPeer
         * @function getTypeUrl
         * @memberof hbb.RegisterPeer
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        RegisterPeer.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.RegisterPeer";
        };

        return RegisterPeer;
    })();

    /**
     * ConnType enum.
     * @name hbb.ConnType
     * @enum {number}
     * @property {number} DEFAULT_CONN=0 DEFAULT_CONN value
     * @property {number} FILE_TRANSFER=1 FILE_TRANSFER value
     * @property {number} PORT_FORWARD=2 PORT_FORWARD value
     * @property {number} RDP=3 RDP value
     * @property {number} VIEW_CAMERA=4 VIEW_CAMERA value
     */
    hbb.ConnType = (function() {
        const valuesById = {}, values = Object.create(valuesById);
        values[valuesById[0] = "DEFAULT_CONN"] = 0;
        values[valuesById[1] = "FILE_TRANSFER"] = 1;
        values[valuesById[2] = "PORT_FORWARD"] = 2;
        values[valuesById[3] = "RDP"] = 3;
        values[valuesById[4] = "VIEW_CAMERA"] = 4;
        return values;
    })();

    hbb.RegisterPeerResponse = (function() {

        /**
         * Properties of a RegisterPeerResponse.
         * @memberof hbb
         * @interface IRegisterPeerResponse
         * @property {boolean|null} [request_pk] RegisterPeerResponse request_pk
         */

        /**
         * Constructs a new RegisterPeerResponse.
         * @memberof hbb
         * @classdesc Represents a RegisterPeerResponse.
         * @implements IRegisterPeerResponse
         * @constructor
         * @param {hbb.IRegisterPeerResponse=} [properties] Properties to set
         */
        function RegisterPeerResponse(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * RegisterPeerResponse request_pk.
         * @member {boolean} request_pk
         * @memberof hbb.RegisterPeerResponse
         * @instance
         */
        RegisterPeerResponse.prototype.request_pk = false;

        /**
         * Creates a new RegisterPeerResponse instance using the specified properties.
         * @function create
         * @memberof hbb.RegisterPeerResponse
         * @static
         * @param {hbb.IRegisterPeerResponse=} [properties] Properties to set
         * @returns {hbb.RegisterPeerResponse} RegisterPeerResponse instance
         */
        RegisterPeerResponse.create = function create(properties) {
            return new RegisterPeerResponse(properties);
        };

        /**
         * Encodes the specified RegisterPeerResponse message. Does not implicitly {@link hbb.RegisterPeerResponse.verify|verify} messages.
         * @function encode
         * @memberof hbb.RegisterPeerResponse
         * @static
         * @param {hbb.IRegisterPeerResponse} message RegisterPeerResponse message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        RegisterPeerResponse.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.request_pk != null && Object.hasOwnProperty.call(message, "request_pk"))
                writer.uint32(/* id 2, wireType 0 =*/16).bool(message.request_pk);
            return writer;
        };

        /**
         * Encodes the specified RegisterPeerResponse message, length delimited. Does not implicitly {@link hbb.RegisterPeerResponse.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.RegisterPeerResponse
         * @static
         * @param {hbb.IRegisterPeerResponse} message RegisterPeerResponse message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        RegisterPeerResponse.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a RegisterPeerResponse message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.RegisterPeerResponse
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.RegisterPeerResponse} RegisterPeerResponse
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        RegisterPeerResponse.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.RegisterPeerResponse();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 2: {
                        message.request_pk = reader.bool();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a RegisterPeerResponse message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.RegisterPeerResponse
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.RegisterPeerResponse} RegisterPeerResponse
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        RegisterPeerResponse.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a RegisterPeerResponse message.
         * @function verify
         * @memberof hbb.RegisterPeerResponse
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        RegisterPeerResponse.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.request_pk != null && message.hasOwnProperty("request_pk"))
                if (typeof message.request_pk !== "boolean")
                    return "request_pk: boolean expected";
            return null;
        };

        /**
         * Creates a RegisterPeerResponse message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.RegisterPeerResponse
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.RegisterPeerResponse} RegisterPeerResponse
         */
        RegisterPeerResponse.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.RegisterPeerResponse)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.RegisterPeerResponse();
            if (object.request_pk != null)
                message.request_pk = Boolean(object.request_pk);
            return message;
        };

        /**
         * Creates a plain object from a RegisterPeerResponse message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.RegisterPeerResponse
         * @static
         * @param {hbb.RegisterPeerResponse} message RegisterPeerResponse
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        RegisterPeerResponse.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults)
                object.request_pk = false;
            if (message.request_pk != null && message.hasOwnProperty("request_pk"))
                object.request_pk = message.request_pk;
            return object;
        };

        /**
         * Converts this RegisterPeerResponse to JSON.
         * @function toJSON
         * @memberof hbb.RegisterPeerResponse
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        RegisterPeerResponse.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for RegisterPeerResponse
         * @function getTypeUrl
         * @memberof hbb.RegisterPeerResponse
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        RegisterPeerResponse.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.RegisterPeerResponse";
        };

        return RegisterPeerResponse;
    })();

    hbb.PunchHoleRequest = (function() {

        /**
         * Properties of a PunchHoleRequest.
         * @memberof hbb
         * @interface IPunchHoleRequest
         * @property {string|null} [id] PunchHoleRequest id
         * @property {hbb.NatType|null} [nat_type] PunchHoleRequest nat_type
         * @property {string|null} [licence_key] PunchHoleRequest licence_key
         * @property {hbb.ConnType|null} [conn_type] PunchHoleRequest conn_type
         * @property {string|null} [token] PunchHoleRequest token
         * @property {string|null} [version] PunchHoleRequest version
         */

        /**
         * Constructs a new PunchHoleRequest.
         * @memberof hbb
         * @classdesc Represents a PunchHoleRequest.
         * @implements IPunchHoleRequest
         * @constructor
         * @param {hbb.IPunchHoleRequest=} [properties] Properties to set
         */
        function PunchHoleRequest(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * PunchHoleRequest id.
         * @member {string} id
         * @memberof hbb.PunchHoleRequest
         * @instance
         */
        PunchHoleRequest.prototype.id = "";

        /**
         * PunchHoleRequest nat_type.
         * @member {hbb.NatType} nat_type
         * @memberof hbb.PunchHoleRequest
         * @instance
         */
        PunchHoleRequest.prototype.nat_type = 0;

        /**
         * PunchHoleRequest licence_key.
         * @member {string} licence_key
         * @memberof hbb.PunchHoleRequest
         * @instance
         */
        PunchHoleRequest.prototype.licence_key = "";

        /**
         * PunchHoleRequest conn_type.
         * @member {hbb.ConnType} conn_type
         * @memberof hbb.PunchHoleRequest
         * @instance
         */
        PunchHoleRequest.prototype.conn_type = 0;

        /**
         * PunchHoleRequest token.
         * @member {string} token
         * @memberof hbb.PunchHoleRequest
         * @instance
         */
        PunchHoleRequest.prototype.token = "";

        /**
         * PunchHoleRequest version.
         * @member {string} version
         * @memberof hbb.PunchHoleRequest
         * @instance
         */
        PunchHoleRequest.prototype.version = "";

        /**
         * Creates a new PunchHoleRequest instance using the specified properties.
         * @function create
         * @memberof hbb.PunchHoleRequest
         * @static
         * @param {hbb.IPunchHoleRequest=} [properties] Properties to set
         * @returns {hbb.PunchHoleRequest} PunchHoleRequest instance
         */
        PunchHoleRequest.create = function create(properties) {
            return new PunchHoleRequest(properties);
        };

        /**
         * Encodes the specified PunchHoleRequest message. Does not implicitly {@link hbb.PunchHoleRequest.verify|verify} messages.
         * @function encode
         * @memberof hbb.PunchHoleRequest
         * @static
         * @param {hbb.IPunchHoleRequest} message PunchHoleRequest message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        PunchHoleRequest.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.id != null && Object.hasOwnProperty.call(message, "id"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.id);
            if (message.nat_type != null && Object.hasOwnProperty.call(message, "nat_type"))
                writer.uint32(/* id 2, wireType 0 =*/16).int32(message.nat_type);
            if (message.licence_key != null && Object.hasOwnProperty.call(message, "licence_key"))
                writer.uint32(/* id 3, wireType 2 =*/26).string(message.licence_key);
            if (message.conn_type != null && Object.hasOwnProperty.call(message, "conn_type"))
                writer.uint32(/* id 4, wireType 0 =*/32).int32(message.conn_type);
            if (message.token != null && Object.hasOwnProperty.call(message, "token"))
                writer.uint32(/* id 5, wireType 2 =*/42).string(message.token);
            if (message.version != null && Object.hasOwnProperty.call(message, "version"))
                writer.uint32(/* id 6, wireType 2 =*/50).string(message.version);
            return writer;
        };

        /**
         * Encodes the specified PunchHoleRequest message, length delimited. Does not implicitly {@link hbb.PunchHoleRequest.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.PunchHoleRequest
         * @static
         * @param {hbb.IPunchHoleRequest} message PunchHoleRequest message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        PunchHoleRequest.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a PunchHoleRequest message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.PunchHoleRequest
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.PunchHoleRequest} PunchHoleRequest
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        PunchHoleRequest.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.PunchHoleRequest();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.id = reader.string();
                        break;
                    }
                case 2: {
                        message.nat_type = reader.int32();
                        break;
                    }
                case 3: {
                        message.licence_key = reader.string();
                        break;
                    }
                case 4: {
                        message.conn_type = reader.int32();
                        break;
                    }
                case 5: {
                        message.token = reader.string();
                        break;
                    }
                case 6: {
                        message.version = reader.string();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a PunchHoleRequest message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.PunchHoleRequest
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.PunchHoleRequest} PunchHoleRequest
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        PunchHoleRequest.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a PunchHoleRequest message.
         * @function verify
         * @memberof hbb.PunchHoleRequest
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        PunchHoleRequest.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.id != null && message.hasOwnProperty("id"))
                if (!$util.isString(message.id))
                    return "id: string expected";
            if (message.nat_type != null && message.hasOwnProperty("nat_type"))
                switch (message.nat_type) {
                default:
                    return "nat_type: enum value expected";
                case 0:
                case 1:
                case 2:
                    break;
                }
            if (message.licence_key != null && message.hasOwnProperty("licence_key"))
                if (!$util.isString(message.licence_key))
                    return "licence_key: string expected";
            if (message.conn_type != null && message.hasOwnProperty("conn_type"))
                switch (message.conn_type) {
                default:
                    return "conn_type: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                case 4:
                    break;
                }
            if (message.token != null && message.hasOwnProperty("token"))
                if (!$util.isString(message.token))
                    return "token: string expected";
            if (message.version != null && message.hasOwnProperty("version"))
                if (!$util.isString(message.version))
                    return "version: string expected";
            return null;
        };

        /**
         * Creates a PunchHoleRequest message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.PunchHoleRequest
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.PunchHoleRequest} PunchHoleRequest
         */
        PunchHoleRequest.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.PunchHoleRequest)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.PunchHoleRequest();
            if (object.id != null)
                message.id = String(object.id);
            switch (object.nat_type) {
            default:
                if (typeof object.nat_type === "number") {
                    message.nat_type = object.nat_type;
                    break;
                }
                break;
            case "UNKNOWN_NAT":
            case 0:
                message.nat_type = 0;
                break;
            case "ASYMMETRIC":
            case 1:
                message.nat_type = 1;
                break;
            case "SYMMETRIC":
            case 2:
                message.nat_type = 2;
                break;
            }
            if (object.licence_key != null)
                message.licence_key = String(object.licence_key);
            switch (object.conn_type) {
            default:
                if (typeof object.conn_type === "number") {
                    message.conn_type = object.conn_type;
                    break;
                }
                break;
            case "DEFAULT_CONN":
            case 0:
                message.conn_type = 0;
                break;
            case "FILE_TRANSFER":
            case 1:
                message.conn_type = 1;
                break;
            case "PORT_FORWARD":
            case 2:
                message.conn_type = 2;
                break;
            case "RDP":
            case 3:
                message.conn_type = 3;
                break;
            case "VIEW_CAMERA":
            case 4:
                message.conn_type = 4;
                break;
            }
            if (object.token != null)
                message.token = String(object.token);
            if (object.version != null)
                message.version = String(object.version);
            return message;
        };

        /**
         * Creates a plain object from a PunchHoleRequest message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.PunchHoleRequest
         * @static
         * @param {hbb.PunchHoleRequest} message PunchHoleRequest
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        PunchHoleRequest.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.id = "";
                object.nat_type = options.enums === String ? "UNKNOWN_NAT" : 0;
                object.licence_key = "";
                object.conn_type = options.enums === String ? "DEFAULT_CONN" : 0;
                object.token = "";
                object.version = "";
            }
            if (message.id != null && message.hasOwnProperty("id"))
                object.id = message.id;
            if (message.nat_type != null && message.hasOwnProperty("nat_type"))
                object.nat_type = options.enums === String ? $root.hbb.NatType[message.nat_type] === undefined ? message.nat_type : $root.hbb.NatType[message.nat_type] : message.nat_type;
            if (message.licence_key != null && message.hasOwnProperty("licence_key"))
                object.licence_key = message.licence_key;
            if (message.conn_type != null && message.hasOwnProperty("conn_type"))
                object.conn_type = options.enums === String ? $root.hbb.ConnType[message.conn_type] === undefined ? message.conn_type : $root.hbb.ConnType[message.conn_type] : message.conn_type;
            if (message.token != null && message.hasOwnProperty("token"))
                object.token = message.token;
            if (message.version != null && message.hasOwnProperty("version"))
                object.version = message.version;
            return object;
        };

        /**
         * Converts this PunchHoleRequest to JSON.
         * @function toJSON
         * @memberof hbb.PunchHoleRequest
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        PunchHoleRequest.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for PunchHoleRequest
         * @function getTypeUrl
         * @memberof hbb.PunchHoleRequest
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        PunchHoleRequest.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.PunchHoleRequest";
        };

        return PunchHoleRequest;
    })();

    hbb.PunchHole = (function() {

        /**
         * Properties of a PunchHole.
         * @memberof hbb
         * @interface IPunchHole
         * @property {Uint8Array|null} [socket_addr] PunchHole socket_addr
         * @property {string|null} [relay_server] PunchHole relay_server
         * @property {hbb.NatType|null} [nat_type] PunchHole nat_type
         */

        /**
         * Constructs a new PunchHole.
         * @memberof hbb
         * @classdesc Represents a PunchHole.
         * @implements IPunchHole
         * @constructor
         * @param {hbb.IPunchHole=} [properties] Properties to set
         */
        function PunchHole(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * PunchHole socket_addr.
         * @member {Uint8Array} socket_addr
         * @memberof hbb.PunchHole
         * @instance
         */
        PunchHole.prototype.socket_addr = $util.newBuffer([]);

        /**
         * PunchHole relay_server.
         * @member {string} relay_server
         * @memberof hbb.PunchHole
         * @instance
         */
        PunchHole.prototype.relay_server = "";

        /**
         * PunchHole nat_type.
         * @member {hbb.NatType} nat_type
         * @memberof hbb.PunchHole
         * @instance
         */
        PunchHole.prototype.nat_type = 0;

        /**
         * Creates a new PunchHole instance using the specified properties.
         * @function create
         * @memberof hbb.PunchHole
         * @static
         * @param {hbb.IPunchHole=} [properties] Properties to set
         * @returns {hbb.PunchHole} PunchHole instance
         */
        PunchHole.create = function create(properties) {
            return new PunchHole(properties);
        };

        /**
         * Encodes the specified PunchHole message. Does not implicitly {@link hbb.PunchHole.verify|verify} messages.
         * @function encode
         * @memberof hbb.PunchHole
         * @static
         * @param {hbb.IPunchHole} message PunchHole message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        PunchHole.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.socket_addr != null && Object.hasOwnProperty.call(message, "socket_addr"))
                writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.socket_addr);
            if (message.relay_server != null && Object.hasOwnProperty.call(message, "relay_server"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.relay_server);
            if (message.nat_type != null && Object.hasOwnProperty.call(message, "nat_type"))
                writer.uint32(/* id 3, wireType 0 =*/24).int32(message.nat_type);
            return writer;
        };

        /**
         * Encodes the specified PunchHole message, length delimited. Does not implicitly {@link hbb.PunchHole.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.PunchHole
         * @static
         * @param {hbb.IPunchHole} message PunchHole message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        PunchHole.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a PunchHole message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.PunchHole
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.PunchHole} PunchHole
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        PunchHole.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.PunchHole();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.socket_addr = reader.bytes();
                        break;
                    }
                case 2: {
                        message.relay_server = reader.string();
                        break;
                    }
                case 3: {
                        message.nat_type = reader.int32();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a PunchHole message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.PunchHole
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.PunchHole} PunchHole
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        PunchHole.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a PunchHole message.
         * @function verify
         * @memberof hbb.PunchHole
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        PunchHole.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.socket_addr != null && message.hasOwnProperty("socket_addr"))
                if (!(message.socket_addr && typeof message.socket_addr.length === "number" || $util.isString(message.socket_addr)))
                    return "socket_addr: buffer expected";
            if (message.relay_server != null && message.hasOwnProperty("relay_server"))
                if (!$util.isString(message.relay_server))
                    return "relay_server: string expected";
            if (message.nat_type != null && message.hasOwnProperty("nat_type"))
                switch (message.nat_type) {
                default:
                    return "nat_type: enum value expected";
                case 0:
                case 1:
                case 2:
                    break;
                }
            return null;
        };

        /**
         * Creates a PunchHole message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.PunchHole
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.PunchHole} PunchHole
         */
        PunchHole.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.PunchHole)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.PunchHole();
            if (object.socket_addr != null)
                if (typeof object.socket_addr === "string")
                    $util.base64.decode(object.socket_addr, message.socket_addr = $util.newBuffer($util.base64.length(object.socket_addr)), 0);
                else if (object.socket_addr.length >= 0)
                    message.socket_addr = object.socket_addr;
            if (object.relay_server != null)
                message.relay_server = String(object.relay_server);
            switch (object.nat_type) {
            default:
                if (typeof object.nat_type === "number") {
                    message.nat_type = object.nat_type;
                    break;
                }
                break;
            case "UNKNOWN_NAT":
            case 0:
                message.nat_type = 0;
                break;
            case "ASYMMETRIC":
            case 1:
                message.nat_type = 1;
                break;
            case "SYMMETRIC":
            case 2:
                message.nat_type = 2;
                break;
            }
            return message;
        };

        /**
         * Creates a plain object from a PunchHole message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.PunchHole
         * @static
         * @param {hbb.PunchHole} message PunchHole
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        PunchHole.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                if (options.bytes === String)
                    object.socket_addr = "";
                else {
                    object.socket_addr = [];
                    if (options.bytes !== Array)
                        object.socket_addr = $util.newBuffer(object.socket_addr);
                }
                object.relay_server = "";
                object.nat_type = options.enums === String ? "UNKNOWN_NAT" : 0;
            }
            if (message.socket_addr != null && message.hasOwnProperty("socket_addr"))
                object.socket_addr = options.bytes === String ? $util.base64.encode(message.socket_addr, 0, message.socket_addr.length) : options.bytes === Array ? Array.prototype.slice.call(message.socket_addr) : message.socket_addr;
            if (message.relay_server != null && message.hasOwnProperty("relay_server"))
                object.relay_server = message.relay_server;
            if (message.nat_type != null && message.hasOwnProperty("nat_type"))
                object.nat_type = options.enums === String ? $root.hbb.NatType[message.nat_type] === undefined ? message.nat_type : $root.hbb.NatType[message.nat_type] : message.nat_type;
            return object;
        };

        /**
         * Converts this PunchHole to JSON.
         * @function toJSON
         * @memberof hbb.PunchHole
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        PunchHole.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for PunchHole
         * @function getTypeUrl
         * @memberof hbb.PunchHole
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        PunchHole.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.PunchHole";
        };

        return PunchHole;
    })();

    hbb.TestNatRequest = (function() {

        /**
         * Properties of a TestNatRequest.
         * @memberof hbb
         * @interface ITestNatRequest
         * @property {number|null} [serial] TestNatRequest serial
         */

        /**
         * Constructs a new TestNatRequest.
         * @memberof hbb
         * @classdesc Represents a TestNatRequest.
         * @implements ITestNatRequest
         * @constructor
         * @param {hbb.ITestNatRequest=} [properties] Properties to set
         */
        function TestNatRequest(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * TestNatRequest serial.
         * @member {number} serial
         * @memberof hbb.TestNatRequest
         * @instance
         */
        TestNatRequest.prototype.serial = 0;

        /**
         * Creates a new TestNatRequest instance using the specified properties.
         * @function create
         * @memberof hbb.TestNatRequest
         * @static
         * @param {hbb.ITestNatRequest=} [properties] Properties to set
         * @returns {hbb.TestNatRequest} TestNatRequest instance
         */
        TestNatRequest.create = function create(properties) {
            return new TestNatRequest(properties);
        };

        /**
         * Encodes the specified TestNatRequest message. Does not implicitly {@link hbb.TestNatRequest.verify|verify} messages.
         * @function encode
         * @memberof hbb.TestNatRequest
         * @static
         * @param {hbb.ITestNatRequest} message TestNatRequest message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        TestNatRequest.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.serial != null && Object.hasOwnProperty.call(message, "serial"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.serial);
            return writer;
        };

        /**
         * Encodes the specified TestNatRequest message, length delimited. Does not implicitly {@link hbb.TestNatRequest.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.TestNatRequest
         * @static
         * @param {hbb.ITestNatRequest} message TestNatRequest message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        TestNatRequest.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a TestNatRequest message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.TestNatRequest
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.TestNatRequest} TestNatRequest
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        TestNatRequest.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.TestNatRequest();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.serial = reader.int32();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a TestNatRequest message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.TestNatRequest
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.TestNatRequest} TestNatRequest
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        TestNatRequest.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a TestNatRequest message.
         * @function verify
         * @memberof hbb.TestNatRequest
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        TestNatRequest.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.serial != null && message.hasOwnProperty("serial"))
                if (!$util.isInteger(message.serial))
                    return "serial: integer expected";
            return null;
        };

        /**
         * Creates a TestNatRequest message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.TestNatRequest
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.TestNatRequest} TestNatRequest
         */
        TestNatRequest.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.TestNatRequest)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.TestNatRequest();
            if (object.serial != null)
                message.serial = object.serial | 0;
            return message;
        };

        /**
         * Creates a plain object from a TestNatRequest message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.TestNatRequest
         * @static
         * @param {hbb.TestNatRequest} message TestNatRequest
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        TestNatRequest.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults)
                object.serial = 0;
            if (message.serial != null && message.hasOwnProperty("serial"))
                object.serial = message.serial;
            return object;
        };

        /**
         * Converts this TestNatRequest to JSON.
         * @function toJSON
         * @memberof hbb.TestNatRequest
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        TestNatRequest.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for TestNatRequest
         * @function getTypeUrl
         * @memberof hbb.TestNatRequest
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        TestNatRequest.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.TestNatRequest";
        };

        return TestNatRequest;
    })();

    hbb.TestNatResponse = (function() {

        /**
         * Properties of a TestNatResponse.
         * @memberof hbb
         * @interface ITestNatResponse
         * @property {number|null} [port] TestNatResponse port
         * @property {hbb.IConfigUpdate|null} [cu] TestNatResponse cu
         */

        /**
         * Constructs a new TestNatResponse.
         * @memberof hbb
         * @classdesc Represents a TestNatResponse.
         * @implements ITestNatResponse
         * @constructor
         * @param {hbb.ITestNatResponse=} [properties] Properties to set
         */
        function TestNatResponse(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * TestNatResponse port.
         * @member {number} port
         * @memberof hbb.TestNatResponse
         * @instance
         */
        TestNatResponse.prototype.port = 0;

        /**
         * TestNatResponse cu.
         * @member {hbb.IConfigUpdate|null|undefined} cu
         * @memberof hbb.TestNatResponse
         * @instance
         */
        TestNatResponse.prototype.cu = null;

        /**
         * Creates a new TestNatResponse instance using the specified properties.
         * @function create
         * @memberof hbb.TestNatResponse
         * @static
         * @param {hbb.ITestNatResponse=} [properties] Properties to set
         * @returns {hbb.TestNatResponse} TestNatResponse instance
         */
        TestNatResponse.create = function create(properties) {
            return new TestNatResponse(properties);
        };

        /**
         * Encodes the specified TestNatResponse message. Does not implicitly {@link hbb.TestNatResponse.verify|verify} messages.
         * @function encode
         * @memberof hbb.TestNatResponse
         * @static
         * @param {hbb.ITestNatResponse} message TestNatResponse message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        TestNatResponse.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.port != null && Object.hasOwnProperty.call(message, "port"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.port);
            if (message.cu != null && Object.hasOwnProperty.call(message, "cu"))
                $root.hbb.ConfigUpdate.encode(message.cu, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified TestNatResponse message, length delimited. Does not implicitly {@link hbb.TestNatResponse.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.TestNatResponse
         * @static
         * @param {hbb.ITestNatResponse} message TestNatResponse message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        TestNatResponse.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a TestNatResponse message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.TestNatResponse
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.TestNatResponse} TestNatResponse
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        TestNatResponse.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.TestNatResponse();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.port = reader.int32();
                        break;
                    }
                case 2: {
                        message.cu = $root.hbb.ConfigUpdate.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a TestNatResponse message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.TestNatResponse
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.TestNatResponse} TestNatResponse
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        TestNatResponse.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a TestNatResponse message.
         * @function verify
         * @memberof hbb.TestNatResponse
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        TestNatResponse.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.port != null && message.hasOwnProperty("port"))
                if (!$util.isInteger(message.port))
                    return "port: integer expected";
            if (message.cu != null && message.hasOwnProperty("cu")) {
                let error = $root.hbb.ConfigUpdate.verify(message.cu, long + 1);
                if (error)
                    return "cu." + error;
            }
            return null;
        };

        /**
         * Creates a TestNatResponse message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.TestNatResponse
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.TestNatResponse} TestNatResponse
         */
        TestNatResponse.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.TestNatResponse)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.TestNatResponse();
            if (object.port != null)
                message.port = object.port | 0;
            if (object.cu != null) {
                if (typeof object.cu !== "object")
                    throw TypeError(".hbb.TestNatResponse.cu: object expected");
                message.cu = $root.hbb.ConfigUpdate.fromObject(object.cu, long + 1);
            }
            return message;
        };

        /**
         * Creates a plain object from a TestNatResponse message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.TestNatResponse
         * @static
         * @param {hbb.TestNatResponse} message TestNatResponse
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        TestNatResponse.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.port = 0;
                object.cu = null;
            }
            if (message.port != null && message.hasOwnProperty("port"))
                object.port = message.port;
            if (message.cu != null && message.hasOwnProperty("cu"))
                object.cu = $root.hbb.ConfigUpdate.toObject(message.cu, options);
            return object;
        };

        /**
         * Converts this TestNatResponse to JSON.
         * @function toJSON
         * @memberof hbb.TestNatResponse
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        TestNatResponse.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for TestNatResponse
         * @function getTypeUrl
         * @memberof hbb.TestNatResponse
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        TestNatResponse.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.TestNatResponse";
        };

        return TestNatResponse;
    })();

    /**
     * NatType enum.
     * @name hbb.NatType
     * @enum {number}
     * @property {number} UNKNOWN_NAT=0 UNKNOWN_NAT value
     * @property {number} ASYMMETRIC=1 ASYMMETRIC value
     * @property {number} SYMMETRIC=2 SYMMETRIC value
     */
    hbb.NatType = (function() {
        const valuesById = {}, values = Object.create(valuesById);
        values[valuesById[0] = "UNKNOWN_NAT"] = 0;
        values[valuesById[1] = "ASYMMETRIC"] = 1;
        values[valuesById[2] = "SYMMETRIC"] = 2;
        return values;
    })();

    hbb.PunchHoleSent = (function() {

        /**
         * Properties of a PunchHoleSent.
         * @memberof hbb
         * @interface IPunchHoleSent
         * @property {Uint8Array|null} [socket_addr] PunchHoleSent socket_addr
         * @property {string|null} [id] PunchHoleSent id
         * @property {string|null} [relay_server] PunchHoleSent relay_server
         * @property {hbb.NatType|null} [nat_type] PunchHoleSent nat_type
         * @property {string|null} [version] PunchHoleSent version
         */

        /**
         * Constructs a new PunchHoleSent.
         * @memberof hbb
         * @classdesc Represents a PunchHoleSent.
         * @implements IPunchHoleSent
         * @constructor
         * @param {hbb.IPunchHoleSent=} [properties] Properties to set
         */
        function PunchHoleSent(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * PunchHoleSent socket_addr.
         * @member {Uint8Array} socket_addr
         * @memberof hbb.PunchHoleSent
         * @instance
         */
        PunchHoleSent.prototype.socket_addr = $util.newBuffer([]);

        /**
         * PunchHoleSent id.
         * @member {string} id
         * @memberof hbb.PunchHoleSent
         * @instance
         */
        PunchHoleSent.prototype.id = "";

        /**
         * PunchHoleSent relay_server.
         * @member {string} relay_server
         * @memberof hbb.PunchHoleSent
         * @instance
         */
        PunchHoleSent.prototype.relay_server = "";

        /**
         * PunchHoleSent nat_type.
         * @member {hbb.NatType} nat_type
         * @memberof hbb.PunchHoleSent
         * @instance
         */
        PunchHoleSent.prototype.nat_type = 0;

        /**
         * PunchHoleSent version.
         * @member {string} version
         * @memberof hbb.PunchHoleSent
         * @instance
         */
        PunchHoleSent.prototype.version = "";

        /**
         * Creates a new PunchHoleSent instance using the specified properties.
         * @function create
         * @memberof hbb.PunchHoleSent
         * @static
         * @param {hbb.IPunchHoleSent=} [properties] Properties to set
         * @returns {hbb.PunchHoleSent} PunchHoleSent instance
         */
        PunchHoleSent.create = function create(properties) {
            return new PunchHoleSent(properties);
        };

        /**
         * Encodes the specified PunchHoleSent message. Does not implicitly {@link hbb.PunchHoleSent.verify|verify} messages.
         * @function encode
         * @memberof hbb.PunchHoleSent
         * @static
         * @param {hbb.IPunchHoleSent} message PunchHoleSent message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        PunchHoleSent.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.socket_addr != null && Object.hasOwnProperty.call(message, "socket_addr"))
                writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.socket_addr);
            if (message.id != null && Object.hasOwnProperty.call(message, "id"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.id);
            if (message.relay_server != null && Object.hasOwnProperty.call(message, "relay_server"))
                writer.uint32(/* id 3, wireType 2 =*/26).string(message.relay_server);
            if (message.nat_type != null && Object.hasOwnProperty.call(message, "nat_type"))
                writer.uint32(/* id 4, wireType 0 =*/32).int32(message.nat_type);
            if (message.version != null && Object.hasOwnProperty.call(message, "version"))
                writer.uint32(/* id 5, wireType 2 =*/42).string(message.version);
            return writer;
        };

        /**
         * Encodes the specified PunchHoleSent message, length delimited. Does not implicitly {@link hbb.PunchHoleSent.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.PunchHoleSent
         * @static
         * @param {hbb.IPunchHoleSent} message PunchHoleSent message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        PunchHoleSent.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a PunchHoleSent message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.PunchHoleSent
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.PunchHoleSent} PunchHoleSent
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        PunchHoleSent.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.PunchHoleSent();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.socket_addr = reader.bytes();
                        break;
                    }
                case 2: {
                        message.id = reader.string();
                        break;
                    }
                case 3: {
                        message.relay_server = reader.string();
                        break;
                    }
                case 4: {
                        message.nat_type = reader.int32();
                        break;
                    }
                case 5: {
                        message.version = reader.string();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a PunchHoleSent message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.PunchHoleSent
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.PunchHoleSent} PunchHoleSent
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        PunchHoleSent.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a PunchHoleSent message.
         * @function verify
         * @memberof hbb.PunchHoleSent
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        PunchHoleSent.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.socket_addr != null && message.hasOwnProperty("socket_addr"))
                if (!(message.socket_addr && typeof message.socket_addr.length === "number" || $util.isString(message.socket_addr)))
                    return "socket_addr: buffer expected";
            if (message.id != null && message.hasOwnProperty("id"))
                if (!$util.isString(message.id))
                    return "id: string expected";
            if (message.relay_server != null && message.hasOwnProperty("relay_server"))
                if (!$util.isString(message.relay_server))
                    return "relay_server: string expected";
            if (message.nat_type != null && message.hasOwnProperty("nat_type"))
                switch (message.nat_type) {
                default:
                    return "nat_type: enum value expected";
                case 0:
                case 1:
                case 2:
                    break;
                }
            if (message.version != null && message.hasOwnProperty("version"))
                if (!$util.isString(message.version))
                    return "version: string expected";
            return null;
        };

        /**
         * Creates a PunchHoleSent message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.PunchHoleSent
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.PunchHoleSent} PunchHoleSent
         */
        PunchHoleSent.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.PunchHoleSent)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.PunchHoleSent();
            if (object.socket_addr != null)
                if (typeof object.socket_addr === "string")
                    $util.base64.decode(object.socket_addr, message.socket_addr = $util.newBuffer($util.base64.length(object.socket_addr)), 0);
                else if (object.socket_addr.length >= 0)
                    message.socket_addr = object.socket_addr;
            if (object.id != null)
                message.id = String(object.id);
            if (object.relay_server != null)
                message.relay_server = String(object.relay_server);
            switch (object.nat_type) {
            default:
                if (typeof object.nat_type === "number") {
                    message.nat_type = object.nat_type;
                    break;
                }
                break;
            case "UNKNOWN_NAT":
            case 0:
                message.nat_type = 0;
                break;
            case "ASYMMETRIC":
            case 1:
                message.nat_type = 1;
                break;
            case "SYMMETRIC":
            case 2:
                message.nat_type = 2;
                break;
            }
            if (object.version != null)
                message.version = String(object.version);
            return message;
        };

        /**
         * Creates a plain object from a PunchHoleSent message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.PunchHoleSent
         * @static
         * @param {hbb.PunchHoleSent} message PunchHoleSent
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        PunchHoleSent.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                if (options.bytes === String)
                    object.socket_addr = "";
                else {
                    object.socket_addr = [];
                    if (options.bytes !== Array)
                        object.socket_addr = $util.newBuffer(object.socket_addr);
                }
                object.id = "";
                object.relay_server = "";
                object.nat_type = options.enums === String ? "UNKNOWN_NAT" : 0;
                object.version = "";
            }
            if (message.socket_addr != null && message.hasOwnProperty("socket_addr"))
                object.socket_addr = options.bytes === String ? $util.base64.encode(message.socket_addr, 0, message.socket_addr.length) : options.bytes === Array ? Array.prototype.slice.call(message.socket_addr) : message.socket_addr;
            if (message.id != null && message.hasOwnProperty("id"))
                object.id = message.id;
            if (message.relay_server != null && message.hasOwnProperty("relay_server"))
                object.relay_server = message.relay_server;
            if (message.nat_type != null && message.hasOwnProperty("nat_type"))
                object.nat_type = options.enums === String ? $root.hbb.NatType[message.nat_type] === undefined ? message.nat_type : $root.hbb.NatType[message.nat_type] : message.nat_type;
            if (message.version != null && message.hasOwnProperty("version"))
                object.version = message.version;
            return object;
        };

        /**
         * Converts this PunchHoleSent to JSON.
         * @function toJSON
         * @memberof hbb.PunchHoleSent
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        PunchHoleSent.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for PunchHoleSent
         * @function getTypeUrl
         * @memberof hbb.PunchHoleSent
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        PunchHoleSent.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.PunchHoleSent";
        };

        return PunchHoleSent;
    })();

    hbb.RegisterPk = (function() {

        /**
         * Properties of a RegisterPk.
         * @memberof hbb
         * @interface IRegisterPk
         * @property {string|null} [id] RegisterPk id
         * @property {Uint8Array|null} [uuid] RegisterPk uuid
         * @property {Uint8Array|null} [pk] RegisterPk pk
         * @property {string|null} [old_id] RegisterPk old_id
         */

        /**
         * Constructs a new RegisterPk.
         * @memberof hbb
         * @classdesc Represents a RegisterPk.
         * @implements IRegisterPk
         * @constructor
         * @param {hbb.IRegisterPk=} [properties] Properties to set
         */
        function RegisterPk(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * RegisterPk id.
         * @member {string} id
         * @memberof hbb.RegisterPk
         * @instance
         */
        RegisterPk.prototype.id = "";

        /**
         * RegisterPk uuid.
         * @member {Uint8Array} uuid
         * @memberof hbb.RegisterPk
         * @instance
         */
        RegisterPk.prototype.uuid = $util.newBuffer([]);

        /**
         * RegisterPk pk.
         * @member {Uint8Array} pk
         * @memberof hbb.RegisterPk
         * @instance
         */
        RegisterPk.prototype.pk = $util.newBuffer([]);

        /**
         * RegisterPk old_id.
         * @member {string} old_id
         * @memberof hbb.RegisterPk
         * @instance
         */
        RegisterPk.prototype.old_id = "";

        /**
         * Creates a new RegisterPk instance using the specified properties.
         * @function create
         * @memberof hbb.RegisterPk
         * @static
         * @param {hbb.IRegisterPk=} [properties] Properties to set
         * @returns {hbb.RegisterPk} RegisterPk instance
         */
        RegisterPk.create = function create(properties) {
            return new RegisterPk(properties);
        };

        /**
         * Encodes the specified RegisterPk message. Does not implicitly {@link hbb.RegisterPk.verify|verify} messages.
         * @function encode
         * @memberof hbb.RegisterPk
         * @static
         * @param {hbb.IRegisterPk} message RegisterPk message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        RegisterPk.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.id != null && Object.hasOwnProperty.call(message, "id"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.id);
            if (message.uuid != null && Object.hasOwnProperty.call(message, "uuid"))
                writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.uuid);
            if (message.pk != null && Object.hasOwnProperty.call(message, "pk"))
                writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.pk);
            if (message.old_id != null && Object.hasOwnProperty.call(message, "old_id"))
                writer.uint32(/* id 4, wireType 2 =*/34).string(message.old_id);
            return writer;
        };

        /**
         * Encodes the specified RegisterPk message, length delimited. Does not implicitly {@link hbb.RegisterPk.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.RegisterPk
         * @static
         * @param {hbb.IRegisterPk} message RegisterPk message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        RegisterPk.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a RegisterPk message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.RegisterPk
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.RegisterPk} RegisterPk
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        RegisterPk.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.RegisterPk();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.id = reader.string();
                        break;
                    }
                case 2: {
                        message.uuid = reader.bytes();
                        break;
                    }
                case 3: {
                        message.pk = reader.bytes();
                        break;
                    }
                case 4: {
                        message.old_id = reader.string();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a RegisterPk message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.RegisterPk
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.RegisterPk} RegisterPk
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        RegisterPk.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a RegisterPk message.
         * @function verify
         * @memberof hbb.RegisterPk
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        RegisterPk.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.id != null && message.hasOwnProperty("id"))
                if (!$util.isString(message.id))
                    return "id: string expected";
            if (message.uuid != null && message.hasOwnProperty("uuid"))
                if (!(message.uuid && typeof message.uuid.length === "number" || $util.isString(message.uuid)))
                    return "uuid: buffer expected";
            if (message.pk != null && message.hasOwnProperty("pk"))
                if (!(message.pk && typeof message.pk.length === "number" || $util.isString(message.pk)))
                    return "pk: buffer expected";
            if (message.old_id != null && message.hasOwnProperty("old_id"))
                if (!$util.isString(message.old_id))
                    return "old_id: string expected";
            return null;
        };

        /**
         * Creates a RegisterPk message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.RegisterPk
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.RegisterPk} RegisterPk
         */
        RegisterPk.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.RegisterPk)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.RegisterPk();
            if (object.id != null)
                message.id = String(object.id);
            if (object.uuid != null)
                if (typeof object.uuid === "string")
                    $util.base64.decode(object.uuid, message.uuid = $util.newBuffer($util.base64.length(object.uuid)), 0);
                else if (object.uuid.length >= 0)
                    message.uuid = object.uuid;
            if (object.pk != null)
                if (typeof object.pk === "string")
                    $util.base64.decode(object.pk, message.pk = $util.newBuffer($util.base64.length(object.pk)), 0);
                else if (object.pk.length >= 0)
                    message.pk = object.pk;
            if (object.old_id != null)
                message.old_id = String(object.old_id);
            return message;
        };

        /**
         * Creates a plain object from a RegisterPk message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.RegisterPk
         * @static
         * @param {hbb.RegisterPk} message RegisterPk
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        RegisterPk.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.id = "";
                if (options.bytes === String)
                    object.uuid = "";
                else {
                    object.uuid = [];
                    if (options.bytes !== Array)
                        object.uuid = $util.newBuffer(object.uuid);
                }
                if (options.bytes === String)
                    object.pk = "";
                else {
                    object.pk = [];
                    if (options.bytes !== Array)
                        object.pk = $util.newBuffer(object.pk);
                }
                object.old_id = "";
            }
            if (message.id != null && message.hasOwnProperty("id"))
                object.id = message.id;
            if (message.uuid != null && message.hasOwnProperty("uuid"))
                object.uuid = options.bytes === String ? $util.base64.encode(message.uuid, 0, message.uuid.length) : options.bytes === Array ? Array.prototype.slice.call(message.uuid) : message.uuid;
            if (message.pk != null && message.hasOwnProperty("pk"))
                object.pk = options.bytes === String ? $util.base64.encode(message.pk, 0, message.pk.length) : options.bytes === Array ? Array.prototype.slice.call(message.pk) : message.pk;
            if (message.old_id != null && message.hasOwnProperty("old_id"))
                object.old_id = message.old_id;
            return object;
        };

        /**
         * Converts this RegisterPk to JSON.
         * @function toJSON
         * @memberof hbb.RegisterPk
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        RegisterPk.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for RegisterPk
         * @function getTypeUrl
         * @memberof hbb.RegisterPk
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        RegisterPk.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.RegisterPk";
        };

        return RegisterPk;
    })();

    hbb.RegisterPkResponse = (function() {

        /**
         * Properties of a RegisterPkResponse.
         * @memberof hbb
         * @interface IRegisterPkResponse
         * @property {hbb.RegisterPkResponse.Result|null} [result] RegisterPkResponse result
         * @property {number|null} [keep_alive] RegisterPkResponse keep_alive
         */

        /**
         * Constructs a new RegisterPkResponse.
         * @memberof hbb
         * @classdesc Represents a RegisterPkResponse.
         * @implements IRegisterPkResponse
         * @constructor
         * @param {hbb.IRegisterPkResponse=} [properties] Properties to set
         */
        function RegisterPkResponse(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * RegisterPkResponse result.
         * @member {hbb.RegisterPkResponse.Result} result
         * @memberof hbb.RegisterPkResponse
         * @instance
         */
        RegisterPkResponse.prototype.result = 0;

        /**
         * RegisterPkResponse keep_alive.
         * @member {number} keep_alive
         * @memberof hbb.RegisterPkResponse
         * @instance
         */
        RegisterPkResponse.prototype.keep_alive = 0;

        /**
         * Creates a new RegisterPkResponse instance using the specified properties.
         * @function create
         * @memberof hbb.RegisterPkResponse
         * @static
         * @param {hbb.IRegisterPkResponse=} [properties] Properties to set
         * @returns {hbb.RegisterPkResponse} RegisterPkResponse instance
         */
        RegisterPkResponse.create = function create(properties) {
            return new RegisterPkResponse(properties);
        };

        /**
         * Encodes the specified RegisterPkResponse message. Does not implicitly {@link hbb.RegisterPkResponse.verify|verify} messages.
         * @function encode
         * @memberof hbb.RegisterPkResponse
         * @static
         * @param {hbb.IRegisterPkResponse} message RegisterPkResponse message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        RegisterPkResponse.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.result != null && Object.hasOwnProperty.call(message, "result"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.result);
            if (message.keep_alive != null && Object.hasOwnProperty.call(message, "keep_alive"))
                writer.uint32(/* id 2, wireType 0 =*/16).int32(message.keep_alive);
            return writer;
        };

        /**
         * Encodes the specified RegisterPkResponse message, length delimited. Does not implicitly {@link hbb.RegisterPkResponse.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.RegisterPkResponse
         * @static
         * @param {hbb.IRegisterPkResponse} message RegisterPkResponse message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        RegisterPkResponse.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a RegisterPkResponse message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.RegisterPkResponse
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.RegisterPkResponse} RegisterPkResponse
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        RegisterPkResponse.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.RegisterPkResponse();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.result = reader.int32();
                        break;
                    }
                case 2: {
                        message.keep_alive = reader.int32();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a RegisterPkResponse message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.RegisterPkResponse
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.RegisterPkResponse} RegisterPkResponse
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        RegisterPkResponse.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a RegisterPkResponse message.
         * @function verify
         * @memberof hbb.RegisterPkResponse
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        RegisterPkResponse.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.result != null && message.hasOwnProperty("result"))
                switch (message.result) {
                default:
                    return "result: enum value expected";
                case 0:
                case 2:
                case 3:
                case 4:
                case 5:
                case 6:
                case 7:
                    break;
                }
            if (message.keep_alive != null && message.hasOwnProperty("keep_alive"))
                if (!$util.isInteger(message.keep_alive))
                    return "keep_alive: integer expected";
            return null;
        };

        /**
         * Creates a RegisterPkResponse message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.RegisterPkResponse
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.RegisterPkResponse} RegisterPkResponse
         */
        RegisterPkResponse.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.RegisterPkResponse)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.RegisterPkResponse();
            switch (object.result) {
            default:
                if (typeof object.result === "number") {
                    message.result = object.result;
                    break;
                }
                break;
            case "OK":
            case 0:
                message.result = 0;
                break;
            case "UUID_MISMATCH":
            case 2:
                message.result = 2;
                break;
            case "ID_EXISTS":
            case 3:
                message.result = 3;
                break;
            case "TOO_FREQUENT":
            case 4:
                message.result = 4;
                break;
            case "INVALID_ID_FORMAT":
            case 5:
                message.result = 5;
                break;
            case "NOT_SUPPORT":
            case 6:
                message.result = 6;
                break;
            case "SERVER_ERROR":
            case 7:
                message.result = 7;
                break;
            }
            if (object.keep_alive != null)
                message.keep_alive = object.keep_alive | 0;
            return message;
        };

        /**
         * Creates a plain object from a RegisterPkResponse message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.RegisterPkResponse
         * @static
         * @param {hbb.RegisterPkResponse} message RegisterPkResponse
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        RegisterPkResponse.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.result = options.enums === String ? "OK" : 0;
                object.keep_alive = 0;
            }
            if (message.result != null && message.hasOwnProperty("result"))
                object.result = options.enums === String ? $root.hbb.RegisterPkResponse.Result[message.result] === undefined ? message.result : $root.hbb.RegisterPkResponse.Result[message.result] : message.result;
            if (message.keep_alive != null && message.hasOwnProperty("keep_alive"))
                object.keep_alive = message.keep_alive;
            return object;
        };

        /**
         * Converts this RegisterPkResponse to JSON.
         * @function toJSON
         * @memberof hbb.RegisterPkResponse
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        RegisterPkResponse.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for RegisterPkResponse
         * @function getTypeUrl
         * @memberof hbb.RegisterPkResponse
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        RegisterPkResponse.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.RegisterPkResponse";
        };

        /**
         * Result enum.
         * @name hbb.RegisterPkResponse.Result
         * @enum {number}
         * @property {number} OK=0 OK value
         * @property {number} UUID_MISMATCH=2 UUID_MISMATCH value
         * @property {number} ID_EXISTS=3 ID_EXISTS value
         * @property {number} TOO_FREQUENT=4 TOO_FREQUENT value
         * @property {number} INVALID_ID_FORMAT=5 INVALID_ID_FORMAT value
         * @property {number} NOT_SUPPORT=6 NOT_SUPPORT value
         * @property {number} SERVER_ERROR=7 SERVER_ERROR value
         */
        RegisterPkResponse.Result = (function() {
            const valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "OK"] = 0;
            values[valuesById[2] = "UUID_MISMATCH"] = 2;
            values[valuesById[3] = "ID_EXISTS"] = 3;
            values[valuesById[4] = "TOO_FREQUENT"] = 4;
            values[valuesById[5] = "INVALID_ID_FORMAT"] = 5;
            values[valuesById[6] = "NOT_SUPPORT"] = 6;
            values[valuesById[7] = "SERVER_ERROR"] = 7;
            return values;
        })();

        return RegisterPkResponse;
    })();

    hbb.PunchHoleResponse = (function() {

        /**
         * Properties of a PunchHoleResponse.
         * @memberof hbb
         * @interface IPunchHoleResponse
         * @property {Uint8Array|null} [socket_addr] PunchHoleResponse socket_addr
         * @property {Uint8Array|null} [pk] PunchHoleResponse pk
         * @property {hbb.PunchHoleResponse.Failure|null} [failure] PunchHoleResponse failure
         * @property {string|null} [relay_server] PunchHoleResponse relay_server
         * @property {hbb.NatType|null} [nat_type] PunchHoleResponse nat_type
         * @property {boolean|null} [is_local] PunchHoleResponse is_local
         * @property {string|null} [other_failure] PunchHoleResponse other_failure
         * @property {number|null} [feedback] PunchHoleResponse feedback
         */

        /**
         * Constructs a new PunchHoleResponse.
         * @memberof hbb
         * @classdesc Represents a PunchHoleResponse.
         * @implements IPunchHoleResponse
         * @constructor
         * @param {hbb.IPunchHoleResponse=} [properties] Properties to set
         */
        function PunchHoleResponse(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * PunchHoleResponse socket_addr.
         * @member {Uint8Array} socket_addr
         * @memberof hbb.PunchHoleResponse
         * @instance
         */
        PunchHoleResponse.prototype.socket_addr = $util.newBuffer([]);

        /**
         * PunchHoleResponse pk.
         * @member {Uint8Array} pk
         * @memberof hbb.PunchHoleResponse
         * @instance
         */
        PunchHoleResponse.prototype.pk = $util.newBuffer([]);

        /**
         * PunchHoleResponse failure.
         * @member {hbb.PunchHoleResponse.Failure} failure
         * @memberof hbb.PunchHoleResponse
         * @instance
         */
        PunchHoleResponse.prototype.failure = 0;

        /**
         * PunchHoleResponse relay_server.
         * @member {string} relay_server
         * @memberof hbb.PunchHoleResponse
         * @instance
         */
        PunchHoleResponse.prototype.relay_server = "";

        /**
         * PunchHoleResponse nat_type.
         * @member {hbb.NatType|null|undefined} nat_type
         * @memberof hbb.PunchHoleResponse
         * @instance
         */
        PunchHoleResponse.prototype.nat_type = null;

        /**
         * PunchHoleResponse is_local.
         * @member {boolean|null|undefined} is_local
         * @memberof hbb.PunchHoleResponse
         * @instance
         */
        PunchHoleResponse.prototype.is_local = null;

        /**
         * PunchHoleResponse other_failure.
         * @member {string} other_failure
         * @memberof hbb.PunchHoleResponse
         * @instance
         */
        PunchHoleResponse.prototype.other_failure = "";

        /**
         * PunchHoleResponse feedback.
         * @member {number} feedback
         * @memberof hbb.PunchHoleResponse
         * @instance
         */
        PunchHoleResponse.prototype.feedback = 0;

        // OneOf field names bound to virtual getters and setters
        let $oneOfFields;

        /**
         * PunchHoleResponse union.
         * @member {"nat_type"|"is_local"|undefined} union
         * @memberof hbb.PunchHoleResponse
         * @instance
         */
        Object.defineProperty(PunchHoleResponse.prototype, "union", {
            get: $util.oneOfGetter($oneOfFields = ["nat_type", "is_local"]),
            set: $util.oneOfSetter($oneOfFields)
        });

        /**
         * Creates a new PunchHoleResponse instance using the specified properties.
         * @function create
         * @memberof hbb.PunchHoleResponse
         * @static
         * @param {hbb.IPunchHoleResponse=} [properties] Properties to set
         * @returns {hbb.PunchHoleResponse} PunchHoleResponse instance
         */
        PunchHoleResponse.create = function create(properties) {
            return new PunchHoleResponse(properties);
        };

        /**
         * Encodes the specified PunchHoleResponse message. Does not implicitly {@link hbb.PunchHoleResponse.verify|verify} messages.
         * @function encode
         * @memberof hbb.PunchHoleResponse
         * @static
         * @param {hbb.IPunchHoleResponse} message PunchHoleResponse message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        PunchHoleResponse.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.socket_addr != null && Object.hasOwnProperty.call(message, "socket_addr"))
                writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.socket_addr);
            if (message.pk != null && Object.hasOwnProperty.call(message, "pk"))
                writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.pk);
            if (message.failure != null && Object.hasOwnProperty.call(message, "failure"))
                writer.uint32(/* id 3, wireType 0 =*/24).int32(message.failure);
            if (message.relay_server != null && Object.hasOwnProperty.call(message, "relay_server"))
                writer.uint32(/* id 4, wireType 2 =*/34).string(message.relay_server);
            if (message.nat_type != null && Object.hasOwnProperty.call(message, "nat_type"))
                writer.uint32(/* id 5, wireType 0 =*/40).int32(message.nat_type);
            if (message.is_local != null && Object.hasOwnProperty.call(message, "is_local"))
                writer.uint32(/* id 6, wireType 0 =*/48).bool(message.is_local);
            if (message.other_failure != null && Object.hasOwnProperty.call(message, "other_failure"))
                writer.uint32(/* id 7, wireType 2 =*/58).string(message.other_failure);
            if (message.feedback != null && Object.hasOwnProperty.call(message, "feedback"))
                writer.uint32(/* id 8, wireType 0 =*/64).int32(message.feedback);
            return writer;
        };

        /**
         * Encodes the specified PunchHoleResponse message, length delimited. Does not implicitly {@link hbb.PunchHoleResponse.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.PunchHoleResponse
         * @static
         * @param {hbb.IPunchHoleResponse} message PunchHoleResponse message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        PunchHoleResponse.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a PunchHoleResponse message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.PunchHoleResponse
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.PunchHoleResponse} PunchHoleResponse
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        PunchHoleResponse.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.PunchHoleResponse();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.socket_addr = reader.bytes();
                        break;
                    }
                case 2: {
                        message.pk = reader.bytes();
                        break;
                    }
                case 3: {
                        message.failure = reader.int32();
                        break;
                    }
                case 4: {
                        message.relay_server = reader.string();
                        break;
                    }
                case 5: {
                        message.nat_type = reader.int32();
                        break;
                    }
                case 6: {
                        message.is_local = reader.bool();
                        break;
                    }
                case 7: {
                        message.other_failure = reader.string();
                        break;
                    }
                case 8: {
                        message.feedback = reader.int32();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a PunchHoleResponse message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.PunchHoleResponse
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.PunchHoleResponse} PunchHoleResponse
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        PunchHoleResponse.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a PunchHoleResponse message.
         * @function verify
         * @memberof hbb.PunchHoleResponse
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        PunchHoleResponse.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            let properties = {};
            if (message.socket_addr != null && message.hasOwnProperty("socket_addr"))
                if (!(message.socket_addr && typeof message.socket_addr.length === "number" || $util.isString(message.socket_addr)))
                    return "socket_addr: buffer expected";
            if (message.pk != null && message.hasOwnProperty("pk"))
                if (!(message.pk && typeof message.pk.length === "number" || $util.isString(message.pk)))
                    return "pk: buffer expected";
            if (message.failure != null && message.hasOwnProperty("failure"))
                switch (message.failure) {
                default:
                    return "failure: enum value expected";
                case 0:
                case 2:
                case 3:
                case 4:
                    break;
                }
            if (message.relay_server != null && message.hasOwnProperty("relay_server"))
                if (!$util.isString(message.relay_server))
                    return "relay_server: string expected";
            if (message.nat_type != null && message.hasOwnProperty("nat_type")) {
                properties.union = 1;
                switch (message.nat_type) {
                default:
                    return "nat_type: enum value expected";
                case 0:
                case 1:
                case 2:
                    break;
                }
            }
            if (message.is_local != null && message.hasOwnProperty("is_local")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                if (typeof message.is_local !== "boolean")
                    return "is_local: boolean expected";
            }
            if (message.other_failure != null && message.hasOwnProperty("other_failure"))
                if (!$util.isString(message.other_failure))
                    return "other_failure: string expected";
            if (message.feedback != null && message.hasOwnProperty("feedback"))
                if (!$util.isInteger(message.feedback))
                    return "feedback: integer expected";
            return null;
        };

        /**
         * Creates a PunchHoleResponse message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.PunchHoleResponse
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.PunchHoleResponse} PunchHoleResponse
         */
        PunchHoleResponse.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.PunchHoleResponse)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.PunchHoleResponse();
            if (object.socket_addr != null)
                if (typeof object.socket_addr === "string")
                    $util.base64.decode(object.socket_addr, message.socket_addr = $util.newBuffer($util.base64.length(object.socket_addr)), 0);
                else if (object.socket_addr.length >= 0)
                    message.socket_addr = object.socket_addr;
            if (object.pk != null)
                if (typeof object.pk === "string")
                    $util.base64.decode(object.pk, message.pk = $util.newBuffer($util.base64.length(object.pk)), 0);
                else if (object.pk.length >= 0)
                    message.pk = object.pk;
            switch (object.failure) {
            default:
                if (typeof object.failure === "number") {
                    message.failure = object.failure;
                    break;
                }
                break;
            case "ID_NOT_EXIST":
            case 0:
                message.failure = 0;
                break;
            case "OFFLINE":
            case 2:
                message.failure = 2;
                break;
            case "LICENSE_MISMATCH":
            case 3:
                message.failure = 3;
                break;
            case "LICENSE_OVERUSE":
            case 4:
                message.failure = 4;
                break;
            }
            if (object.relay_server != null)
                message.relay_server = String(object.relay_server);
            switch (object.nat_type) {
            default:
                if (typeof object.nat_type === "number") {
                    message.nat_type = object.nat_type;
                    break;
                }
                break;
            case "UNKNOWN_NAT":
            case 0:
                message.nat_type = 0;
                break;
            case "ASYMMETRIC":
            case 1:
                message.nat_type = 1;
                break;
            case "SYMMETRIC":
            case 2:
                message.nat_type = 2;
                break;
            }
            if (object.is_local != null)
                message.is_local = Boolean(object.is_local);
            if (object.other_failure != null)
                message.other_failure = String(object.other_failure);
            if (object.feedback != null)
                message.feedback = object.feedback | 0;
            return message;
        };

        /**
         * Creates a plain object from a PunchHoleResponse message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.PunchHoleResponse
         * @static
         * @param {hbb.PunchHoleResponse} message PunchHoleResponse
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        PunchHoleResponse.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                if (options.bytes === String)
                    object.socket_addr = "";
                else {
                    object.socket_addr = [];
                    if (options.bytes !== Array)
                        object.socket_addr = $util.newBuffer(object.socket_addr);
                }
                if (options.bytes === String)
                    object.pk = "";
                else {
                    object.pk = [];
                    if (options.bytes !== Array)
                        object.pk = $util.newBuffer(object.pk);
                }
                object.failure = options.enums === String ? "ID_NOT_EXIST" : 0;
                object.relay_server = "";
                object.other_failure = "";
                object.feedback = 0;
            }
            if (message.socket_addr != null && message.hasOwnProperty("socket_addr"))
                object.socket_addr = options.bytes === String ? $util.base64.encode(message.socket_addr, 0, message.socket_addr.length) : options.bytes === Array ? Array.prototype.slice.call(message.socket_addr) : message.socket_addr;
            if (message.pk != null && message.hasOwnProperty("pk"))
                object.pk = options.bytes === String ? $util.base64.encode(message.pk, 0, message.pk.length) : options.bytes === Array ? Array.prototype.slice.call(message.pk) : message.pk;
            if (message.failure != null && message.hasOwnProperty("failure"))
                object.failure = options.enums === String ? $root.hbb.PunchHoleResponse.Failure[message.failure] === undefined ? message.failure : $root.hbb.PunchHoleResponse.Failure[message.failure] : message.failure;
            if (message.relay_server != null && message.hasOwnProperty("relay_server"))
                object.relay_server = message.relay_server;
            if (message.nat_type != null && message.hasOwnProperty("nat_type")) {
                object.nat_type = options.enums === String ? $root.hbb.NatType[message.nat_type] === undefined ? message.nat_type : $root.hbb.NatType[message.nat_type] : message.nat_type;
                if (options.oneofs)
                    object.union = "nat_type";
            }
            if (message.is_local != null && message.hasOwnProperty("is_local")) {
                object.is_local = message.is_local;
                if (options.oneofs)
                    object.union = "is_local";
            }
            if (message.other_failure != null && message.hasOwnProperty("other_failure"))
                object.other_failure = message.other_failure;
            if (message.feedback != null && message.hasOwnProperty("feedback"))
                object.feedback = message.feedback;
            return object;
        };

        /**
         * Converts this PunchHoleResponse to JSON.
         * @function toJSON
         * @memberof hbb.PunchHoleResponse
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        PunchHoleResponse.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for PunchHoleResponse
         * @function getTypeUrl
         * @memberof hbb.PunchHoleResponse
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        PunchHoleResponse.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.PunchHoleResponse";
        };

        /**
         * Failure enum.
         * @name hbb.PunchHoleResponse.Failure
         * @enum {number}
         * @property {number} ID_NOT_EXIST=0 ID_NOT_EXIST value
         * @property {number} OFFLINE=2 OFFLINE value
         * @property {number} LICENSE_MISMATCH=3 LICENSE_MISMATCH value
         * @property {number} LICENSE_OVERUSE=4 LICENSE_OVERUSE value
         */
        PunchHoleResponse.Failure = (function() {
            const valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "ID_NOT_EXIST"] = 0;
            values[valuesById[2] = "OFFLINE"] = 2;
            values[valuesById[3] = "LICENSE_MISMATCH"] = 3;
            values[valuesById[4] = "LICENSE_OVERUSE"] = 4;
            return values;
        })();

        return PunchHoleResponse;
    })();

    hbb.ConfigUpdate = (function() {

        /**
         * Properties of a ConfigUpdate.
         * @memberof hbb
         * @interface IConfigUpdate
         * @property {number|null} [serial] ConfigUpdate serial
         * @property {Array.<string>|null} [rendezvous_servers] ConfigUpdate rendezvous_servers
         */

        /**
         * Constructs a new ConfigUpdate.
         * @memberof hbb
         * @classdesc Represents a ConfigUpdate.
         * @implements IConfigUpdate
         * @constructor
         * @param {hbb.IConfigUpdate=} [properties] Properties to set
         */
        function ConfigUpdate(properties) {
            this.rendezvous_servers = [];
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ConfigUpdate serial.
         * @member {number} serial
         * @memberof hbb.ConfigUpdate
         * @instance
         */
        ConfigUpdate.prototype.serial = 0;

        /**
         * ConfigUpdate rendezvous_servers.
         * @member {Array.<string>} rendezvous_servers
         * @memberof hbb.ConfigUpdate
         * @instance
         */
        ConfigUpdate.prototype.rendezvous_servers = $util.emptyArray;

        /**
         * Creates a new ConfigUpdate instance using the specified properties.
         * @function create
         * @memberof hbb.ConfigUpdate
         * @static
         * @param {hbb.IConfigUpdate=} [properties] Properties to set
         * @returns {hbb.ConfigUpdate} ConfigUpdate instance
         */
        ConfigUpdate.create = function create(properties) {
            return new ConfigUpdate(properties);
        };

        /**
         * Encodes the specified ConfigUpdate message. Does not implicitly {@link hbb.ConfigUpdate.verify|verify} messages.
         * @function encode
         * @memberof hbb.ConfigUpdate
         * @static
         * @param {hbb.IConfigUpdate} message ConfigUpdate message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ConfigUpdate.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.serial != null && Object.hasOwnProperty.call(message, "serial"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.serial);
            if (message.rendezvous_servers != null && message.rendezvous_servers.length)
                for (let i = 0; i < message.rendezvous_servers.length; ++i)
                    writer.uint32(/* id 2, wireType 2 =*/18).string(message.rendezvous_servers[i]);
            return writer;
        };

        /**
         * Encodes the specified ConfigUpdate message, length delimited. Does not implicitly {@link hbb.ConfigUpdate.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.ConfigUpdate
         * @static
         * @param {hbb.IConfigUpdate} message ConfigUpdate message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ConfigUpdate.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a ConfigUpdate message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.ConfigUpdate
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.ConfigUpdate} ConfigUpdate
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ConfigUpdate.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.ConfigUpdate();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.serial = reader.int32();
                        break;
                    }
                case 2: {
                        if (!(message.rendezvous_servers && message.rendezvous_servers.length))
                            message.rendezvous_servers = [];
                        message.rendezvous_servers.push(reader.string());
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a ConfigUpdate message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.ConfigUpdate
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.ConfigUpdate} ConfigUpdate
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ConfigUpdate.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a ConfigUpdate message.
         * @function verify
         * @memberof hbb.ConfigUpdate
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ConfigUpdate.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.serial != null && message.hasOwnProperty("serial"))
                if (!$util.isInteger(message.serial))
                    return "serial: integer expected";
            if (message.rendezvous_servers != null && message.hasOwnProperty("rendezvous_servers")) {
                if (!Array.isArray(message.rendezvous_servers))
                    return "rendezvous_servers: array expected";
                for (let i = 0; i < message.rendezvous_servers.length; ++i)
                    if (!$util.isString(message.rendezvous_servers[i]))
                        return "rendezvous_servers: string[] expected";
            }
            return null;
        };

        /**
         * Creates a ConfigUpdate message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.ConfigUpdate
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.ConfigUpdate} ConfigUpdate
         */
        ConfigUpdate.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.ConfigUpdate)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.ConfigUpdate();
            if (object.serial != null)
                message.serial = object.serial | 0;
            if (object.rendezvous_servers) {
                if (!Array.isArray(object.rendezvous_servers))
                    throw TypeError(".hbb.ConfigUpdate.rendezvous_servers: array expected");
                message.rendezvous_servers = [];
                for (let i = 0; i < object.rendezvous_servers.length; ++i)
                    message.rendezvous_servers[i] = String(object.rendezvous_servers[i]);
            }
            return message;
        };

        /**
         * Creates a plain object from a ConfigUpdate message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.ConfigUpdate
         * @static
         * @param {hbb.ConfigUpdate} message ConfigUpdate
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ConfigUpdate.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.arrays || options.defaults)
                object.rendezvous_servers = [];
            if (options.defaults)
                object.serial = 0;
            if (message.serial != null && message.hasOwnProperty("serial"))
                object.serial = message.serial;
            if (message.rendezvous_servers && message.rendezvous_servers.length) {
                object.rendezvous_servers = [];
                for (let j = 0; j < message.rendezvous_servers.length; ++j)
                    object.rendezvous_servers[j] = message.rendezvous_servers[j];
            }
            return object;
        };

        /**
         * Converts this ConfigUpdate to JSON.
         * @function toJSON
         * @memberof hbb.ConfigUpdate
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ConfigUpdate.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for ConfigUpdate
         * @function getTypeUrl
         * @memberof hbb.ConfigUpdate
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        ConfigUpdate.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.ConfigUpdate";
        };

        return ConfigUpdate;
    })();

    hbb.RequestRelay = (function() {

        /**
         * Properties of a RequestRelay.
         * @memberof hbb
         * @interface IRequestRelay
         * @property {string|null} [id] RequestRelay id
         * @property {string|null} [uuid] RequestRelay uuid
         * @property {Uint8Array|null} [socket_addr] RequestRelay socket_addr
         * @property {string|null} [relay_server] RequestRelay relay_server
         * @property {boolean|null} [secure] RequestRelay secure
         * @property {string|null} [licence_key] RequestRelay licence_key
         * @property {hbb.ConnType|null} [conn_type] RequestRelay conn_type
         * @property {string|null} [token] RequestRelay token
         */

        /**
         * Constructs a new RequestRelay.
         * @memberof hbb
         * @classdesc Represents a RequestRelay.
         * @implements IRequestRelay
         * @constructor
         * @param {hbb.IRequestRelay=} [properties] Properties to set
         */
        function RequestRelay(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * RequestRelay id.
         * @member {string} id
         * @memberof hbb.RequestRelay
         * @instance
         */
        RequestRelay.prototype.id = "";

        /**
         * RequestRelay uuid.
         * @member {string} uuid
         * @memberof hbb.RequestRelay
         * @instance
         */
        RequestRelay.prototype.uuid = "";

        /**
         * RequestRelay socket_addr.
         * @member {Uint8Array} socket_addr
         * @memberof hbb.RequestRelay
         * @instance
         */
        RequestRelay.prototype.socket_addr = $util.newBuffer([]);

        /**
         * RequestRelay relay_server.
         * @member {string} relay_server
         * @memberof hbb.RequestRelay
         * @instance
         */
        RequestRelay.prototype.relay_server = "";

        /**
         * RequestRelay secure.
         * @member {boolean} secure
         * @memberof hbb.RequestRelay
         * @instance
         */
        RequestRelay.prototype.secure = false;

        /**
         * RequestRelay licence_key.
         * @member {string} licence_key
         * @memberof hbb.RequestRelay
         * @instance
         */
        RequestRelay.prototype.licence_key = "";

        /**
         * RequestRelay conn_type.
         * @member {hbb.ConnType} conn_type
         * @memberof hbb.RequestRelay
         * @instance
         */
        RequestRelay.prototype.conn_type = 0;

        /**
         * RequestRelay token.
         * @member {string} token
         * @memberof hbb.RequestRelay
         * @instance
         */
        RequestRelay.prototype.token = "";

        /**
         * Creates a new RequestRelay instance using the specified properties.
         * @function create
         * @memberof hbb.RequestRelay
         * @static
         * @param {hbb.IRequestRelay=} [properties] Properties to set
         * @returns {hbb.RequestRelay} RequestRelay instance
         */
        RequestRelay.create = function create(properties) {
            return new RequestRelay(properties);
        };

        /**
         * Encodes the specified RequestRelay message. Does not implicitly {@link hbb.RequestRelay.verify|verify} messages.
         * @function encode
         * @memberof hbb.RequestRelay
         * @static
         * @param {hbb.IRequestRelay} message RequestRelay message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        RequestRelay.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.id != null && Object.hasOwnProperty.call(message, "id"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.id);
            if (message.uuid != null && Object.hasOwnProperty.call(message, "uuid"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.uuid);
            if (message.socket_addr != null && Object.hasOwnProperty.call(message, "socket_addr"))
                writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.socket_addr);
            if (message.relay_server != null && Object.hasOwnProperty.call(message, "relay_server"))
                writer.uint32(/* id 4, wireType 2 =*/34).string(message.relay_server);
            if (message.secure != null && Object.hasOwnProperty.call(message, "secure"))
                writer.uint32(/* id 5, wireType 0 =*/40).bool(message.secure);
            if (message.licence_key != null && Object.hasOwnProperty.call(message, "licence_key"))
                writer.uint32(/* id 6, wireType 2 =*/50).string(message.licence_key);
            if (message.conn_type != null && Object.hasOwnProperty.call(message, "conn_type"))
                writer.uint32(/* id 7, wireType 0 =*/56).int32(message.conn_type);
            if (message.token != null && Object.hasOwnProperty.call(message, "token"))
                writer.uint32(/* id 8, wireType 2 =*/66).string(message.token);
            return writer;
        };

        /**
         * Encodes the specified RequestRelay message, length delimited. Does not implicitly {@link hbb.RequestRelay.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.RequestRelay
         * @static
         * @param {hbb.IRequestRelay} message RequestRelay message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        RequestRelay.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a RequestRelay message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.RequestRelay
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.RequestRelay} RequestRelay
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        RequestRelay.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.RequestRelay();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.id = reader.string();
                        break;
                    }
                case 2: {
                        message.uuid = reader.string();
                        break;
                    }
                case 3: {
                        message.socket_addr = reader.bytes();
                        break;
                    }
                case 4: {
                        message.relay_server = reader.string();
                        break;
                    }
                case 5: {
                        message.secure = reader.bool();
                        break;
                    }
                case 6: {
                        message.licence_key = reader.string();
                        break;
                    }
                case 7: {
                        message.conn_type = reader.int32();
                        break;
                    }
                case 8: {
                        message.token = reader.string();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a RequestRelay message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.RequestRelay
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.RequestRelay} RequestRelay
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        RequestRelay.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a RequestRelay message.
         * @function verify
         * @memberof hbb.RequestRelay
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        RequestRelay.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.id != null && message.hasOwnProperty("id"))
                if (!$util.isString(message.id))
                    return "id: string expected";
            if (message.uuid != null && message.hasOwnProperty("uuid"))
                if (!$util.isString(message.uuid))
                    return "uuid: string expected";
            if (message.socket_addr != null && message.hasOwnProperty("socket_addr"))
                if (!(message.socket_addr && typeof message.socket_addr.length === "number" || $util.isString(message.socket_addr)))
                    return "socket_addr: buffer expected";
            if (message.relay_server != null && message.hasOwnProperty("relay_server"))
                if (!$util.isString(message.relay_server))
                    return "relay_server: string expected";
            if (message.secure != null && message.hasOwnProperty("secure"))
                if (typeof message.secure !== "boolean")
                    return "secure: boolean expected";
            if (message.licence_key != null && message.hasOwnProperty("licence_key"))
                if (!$util.isString(message.licence_key))
                    return "licence_key: string expected";
            if (message.conn_type != null && message.hasOwnProperty("conn_type"))
                switch (message.conn_type) {
                default:
                    return "conn_type: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                case 4:
                    break;
                }
            if (message.token != null && message.hasOwnProperty("token"))
                if (!$util.isString(message.token))
                    return "token: string expected";
            return null;
        };

        /**
         * Creates a RequestRelay message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.RequestRelay
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.RequestRelay} RequestRelay
         */
        RequestRelay.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.RequestRelay)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.RequestRelay();
            if (object.id != null)
                message.id = String(object.id);
            if (object.uuid != null)
                message.uuid = String(object.uuid);
            if (object.socket_addr != null)
                if (typeof object.socket_addr === "string")
                    $util.base64.decode(object.socket_addr, message.socket_addr = $util.newBuffer($util.base64.length(object.socket_addr)), 0);
                else if (object.socket_addr.length >= 0)
                    message.socket_addr = object.socket_addr;
            if (object.relay_server != null)
                message.relay_server = String(object.relay_server);
            if (object.secure != null)
                message.secure = Boolean(object.secure);
            if (object.licence_key != null)
                message.licence_key = String(object.licence_key);
            switch (object.conn_type) {
            default:
                if (typeof object.conn_type === "number") {
                    message.conn_type = object.conn_type;
                    break;
                }
                break;
            case "DEFAULT_CONN":
            case 0:
                message.conn_type = 0;
                break;
            case "FILE_TRANSFER":
            case 1:
                message.conn_type = 1;
                break;
            case "PORT_FORWARD":
            case 2:
                message.conn_type = 2;
                break;
            case "RDP":
            case 3:
                message.conn_type = 3;
                break;
            case "VIEW_CAMERA":
            case 4:
                message.conn_type = 4;
                break;
            }
            if (object.token != null)
                message.token = String(object.token);
            return message;
        };

        /**
         * Creates a plain object from a RequestRelay message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.RequestRelay
         * @static
         * @param {hbb.RequestRelay} message RequestRelay
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        RequestRelay.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.id = "";
                object.uuid = "";
                if (options.bytes === String)
                    object.socket_addr = "";
                else {
                    object.socket_addr = [];
                    if (options.bytes !== Array)
                        object.socket_addr = $util.newBuffer(object.socket_addr);
                }
                object.relay_server = "";
                object.secure = false;
                object.licence_key = "";
                object.conn_type = options.enums === String ? "DEFAULT_CONN" : 0;
                object.token = "";
            }
            if (message.id != null && message.hasOwnProperty("id"))
                object.id = message.id;
            if (message.uuid != null && message.hasOwnProperty("uuid"))
                object.uuid = message.uuid;
            if (message.socket_addr != null && message.hasOwnProperty("socket_addr"))
                object.socket_addr = options.bytes === String ? $util.base64.encode(message.socket_addr, 0, message.socket_addr.length) : options.bytes === Array ? Array.prototype.slice.call(message.socket_addr) : message.socket_addr;
            if (message.relay_server != null && message.hasOwnProperty("relay_server"))
                object.relay_server = message.relay_server;
            if (message.secure != null && message.hasOwnProperty("secure"))
                object.secure = message.secure;
            if (message.licence_key != null && message.hasOwnProperty("licence_key"))
                object.licence_key = message.licence_key;
            if (message.conn_type != null && message.hasOwnProperty("conn_type"))
                object.conn_type = options.enums === String ? $root.hbb.ConnType[message.conn_type] === undefined ? message.conn_type : $root.hbb.ConnType[message.conn_type] : message.conn_type;
            if (message.token != null && message.hasOwnProperty("token"))
                object.token = message.token;
            return object;
        };

        /**
         * Converts this RequestRelay to JSON.
         * @function toJSON
         * @memberof hbb.RequestRelay
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        RequestRelay.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for RequestRelay
         * @function getTypeUrl
         * @memberof hbb.RequestRelay
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        RequestRelay.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.RequestRelay";
        };

        return RequestRelay;
    })();

    hbb.RelayResponse = (function() {

        /**
         * Properties of a RelayResponse.
         * @memberof hbb
         * @interface IRelayResponse
         * @property {Uint8Array|null} [socket_addr] RelayResponse socket_addr
         * @property {string|null} [uuid] RelayResponse uuid
         * @property {string|null} [relay_server] RelayResponse relay_server
         * @property {string|null} [id] RelayResponse id
         * @property {Uint8Array|null} [pk] RelayResponse pk
         * @property {string|null} [refuse_reason] RelayResponse refuse_reason
         * @property {string|null} [version] RelayResponse version
         * @property {number|null} [feedback] RelayResponse feedback
         */

        /**
         * Constructs a new RelayResponse.
         * @memberof hbb
         * @classdesc Represents a RelayResponse.
         * @implements IRelayResponse
         * @constructor
         * @param {hbb.IRelayResponse=} [properties] Properties to set
         */
        function RelayResponse(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * RelayResponse socket_addr.
         * @member {Uint8Array} socket_addr
         * @memberof hbb.RelayResponse
         * @instance
         */
        RelayResponse.prototype.socket_addr = $util.newBuffer([]);

        /**
         * RelayResponse uuid.
         * @member {string} uuid
         * @memberof hbb.RelayResponse
         * @instance
         */
        RelayResponse.prototype.uuid = "";

        /**
         * RelayResponse relay_server.
         * @member {string} relay_server
         * @memberof hbb.RelayResponse
         * @instance
         */
        RelayResponse.prototype.relay_server = "";

        /**
         * RelayResponse id.
         * @member {string|null|undefined} id
         * @memberof hbb.RelayResponse
         * @instance
         */
        RelayResponse.prototype.id = null;

        /**
         * RelayResponse pk.
         * @member {Uint8Array|null|undefined} pk
         * @memberof hbb.RelayResponse
         * @instance
         */
        RelayResponse.prototype.pk = null;

        /**
         * RelayResponse refuse_reason.
         * @member {string} refuse_reason
         * @memberof hbb.RelayResponse
         * @instance
         */
        RelayResponse.prototype.refuse_reason = "";

        /**
         * RelayResponse version.
         * @member {string} version
         * @memberof hbb.RelayResponse
         * @instance
         */
        RelayResponse.prototype.version = "";

        /**
         * RelayResponse feedback.
         * @member {number} feedback
         * @memberof hbb.RelayResponse
         * @instance
         */
        RelayResponse.prototype.feedback = 0;

        // OneOf field names bound to virtual getters and setters
        let $oneOfFields;

        /**
         * RelayResponse union.
         * @member {"id"|"pk"|undefined} union
         * @memberof hbb.RelayResponse
         * @instance
         */
        Object.defineProperty(RelayResponse.prototype, "union", {
            get: $util.oneOfGetter($oneOfFields = ["id", "pk"]),
            set: $util.oneOfSetter($oneOfFields)
        });

        /**
         * Creates a new RelayResponse instance using the specified properties.
         * @function create
         * @memberof hbb.RelayResponse
         * @static
         * @param {hbb.IRelayResponse=} [properties] Properties to set
         * @returns {hbb.RelayResponse} RelayResponse instance
         */
        RelayResponse.create = function create(properties) {
            return new RelayResponse(properties);
        };

        /**
         * Encodes the specified RelayResponse message. Does not implicitly {@link hbb.RelayResponse.verify|verify} messages.
         * @function encode
         * @memberof hbb.RelayResponse
         * @static
         * @param {hbb.IRelayResponse} message RelayResponse message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        RelayResponse.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.socket_addr != null && Object.hasOwnProperty.call(message, "socket_addr"))
                writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.socket_addr);
            if (message.uuid != null && Object.hasOwnProperty.call(message, "uuid"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.uuid);
            if (message.relay_server != null && Object.hasOwnProperty.call(message, "relay_server"))
                writer.uint32(/* id 3, wireType 2 =*/26).string(message.relay_server);
            if (message.id != null && Object.hasOwnProperty.call(message, "id"))
                writer.uint32(/* id 4, wireType 2 =*/34).string(message.id);
            if (message.pk != null && Object.hasOwnProperty.call(message, "pk"))
                writer.uint32(/* id 5, wireType 2 =*/42).bytes(message.pk);
            if (message.refuse_reason != null && Object.hasOwnProperty.call(message, "refuse_reason"))
                writer.uint32(/* id 6, wireType 2 =*/50).string(message.refuse_reason);
            if (message.version != null && Object.hasOwnProperty.call(message, "version"))
                writer.uint32(/* id 7, wireType 2 =*/58).string(message.version);
            if (message.feedback != null && Object.hasOwnProperty.call(message, "feedback"))
                writer.uint32(/* id 9, wireType 0 =*/72).int32(message.feedback);
            return writer;
        };

        /**
         * Encodes the specified RelayResponse message, length delimited. Does not implicitly {@link hbb.RelayResponse.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.RelayResponse
         * @static
         * @param {hbb.IRelayResponse} message RelayResponse message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        RelayResponse.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a RelayResponse message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.RelayResponse
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.RelayResponse} RelayResponse
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        RelayResponse.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.RelayResponse();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.socket_addr = reader.bytes();
                        break;
                    }
                case 2: {
                        message.uuid = reader.string();
                        break;
                    }
                case 3: {
                        message.relay_server = reader.string();
                        break;
                    }
                case 4: {
                        message.id = reader.string();
                        break;
                    }
                case 5: {
                        message.pk = reader.bytes();
                        break;
                    }
                case 6: {
                        message.refuse_reason = reader.string();
                        break;
                    }
                case 7: {
                        message.version = reader.string();
                        break;
                    }
                case 9: {
                        message.feedback = reader.int32();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a RelayResponse message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.RelayResponse
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.RelayResponse} RelayResponse
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        RelayResponse.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a RelayResponse message.
         * @function verify
         * @memberof hbb.RelayResponse
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        RelayResponse.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            let properties = {};
            if (message.socket_addr != null && message.hasOwnProperty("socket_addr"))
                if (!(message.socket_addr && typeof message.socket_addr.length === "number" || $util.isString(message.socket_addr)))
                    return "socket_addr: buffer expected";
            if (message.uuid != null && message.hasOwnProperty("uuid"))
                if (!$util.isString(message.uuid))
                    return "uuid: string expected";
            if (message.relay_server != null && message.hasOwnProperty("relay_server"))
                if (!$util.isString(message.relay_server))
                    return "relay_server: string expected";
            if (message.id != null && message.hasOwnProperty("id")) {
                properties.union = 1;
                if (!$util.isString(message.id))
                    return "id: string expected";
            }
            if (message.pk != null && message.hasOwnProperty("pk")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                if (!(message.pk && typeof message.pk.length === "number" || $util.isString(message.pk)))
                    return "pk: buffer expected";
            }
            if (message.refuse_reason != null && message.hasOwnProperty("refuse_reason"))
                if (!$util.isString(message.refuse_reason))
                    return "refuse_reason: string expected";
            if (message.version != null && message.hasOwnProperty("version"))
                if (!$util.isString(message.version))
                    return "version: string expected";
            if (message.feedback != null && message.hasOwnProperty("feedback"))
                if (!$util.isInteger(message.feedback))
                    return "feedback: integer expected";
            return null;
        };

        /**
         * Creates a RelayResponse message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.RelayResponse
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.RelayResponse} RelayResponse
         */
        RelayResponse.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.RelayResponse)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.RelayResponse();
            if (object.socket_addr != null)
                if (typeof object.socket_addr === "string")
                    $util.base64.decode(object.socket_addr, message.socket_addr = $util.newBuffer($util.base64.length(object.socket_addr)), 0);
                else if (object.socket_addr.length >= 0)
                    message.socket_addr = object.socket_addr;
            if (object.uuid != null)
                message.uuid = String(object.uuid);
            if (object.relay_server != null)
                message.relay_server = String(object.relay_server);
            if (object.id != null)
                message.id = String(object.id);
            if (object.pk != null)
                if (typeof object.pk === "string")
                    $util.base64.decode(object.pk, message.pk = $util.newBuffer($util.base64.length(object.pk)), 0);
                else if (object.pk.length >= 0)
                    message.pk = object.pk;
            if (object.refuse_reason != null)
                message.refuse_reason = String(object.refuse_reason);
            if (object.version != null)
                message.version = String(object.version);
            if (object.feedback != null)
                message.feedback = object.feedback | 0;
            return message;
        };

        /**
         * Creates a plain object from a RelayResponse message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.RelayResponse
         * @static
         * @param {hbb.RelayResponse} message RelayResponse
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        RelayResponse.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                if (options.bytes === String)
                    object.socket_addr = "";
                else {
                    object.socket_addr = [];
                    if (options.bytes !== Array)
                        object.socket_addr = $util.newBuffer(object.socket_addr);
                }
                object.uuid = "";
                object.relay_server = "";
                object.refuse_reason = "";
                object.version = "";
                object.feedback = 0;
            }
            if (message.socket_addr != null && message.hasOwnProperty("socket_addr"))
                object.socket_addr = options.bytes === String ? $util.base64.encode(message.socket_addr, 0, message.socket_addr.length) : options.bytes === Array ? Array.prototype.slice.call(message.socket_addr) : message.socket_addr;
            if (message.uuid != null && message.hasOwnProperty("uuid"))
                object.uuid = message.uuid;
            if (message.relay_server != null && message.hasOwnProperty("relay_server"))
                object.relay_server = message.relay_server;
            if (message.id != null && message.hasOwnProperty("id")) {
                object.id = message.id;
                if (options.oneofs)
                    object.union = "id";
            }
            if (message.pk != null && message.hasOwnProperty("pk")) {
                object.pk = options.bytes === String ? $util.base64.encode(message.pk, 0, message.pk.length) : options.bytes === Array ? Array.prototype.slice.call(message.pk) : message.pk;
                if (options.oneofs)
                    object.union = "pk";
            }
            if (message.refuse_reason != null && message.hasOwnProperty("refuse_reason"))
                object.refuse_reason = message.refuse_reason;
            if (message.version != null && message.hasOwnProperty("version"))
                object.version = message.version;
            if (message.feedback != null && message.hasOwnProperty("feedback"))
                object.feedback = message.feedback;
            return object;
        };

        /**
         * Converts this RelayResponse to JSON.
         * @function toJSON
         * @memberof hbb.RelayResponse
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        RelayResponse.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for RelayResponse
         * @function getTypeUrl
         * @memberof hbb.RelayResponse
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        RelayResponse.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.RelayResponse";
        };

        return RelayResponse;
    })();

    hbb.SoftwareUpdate = (function() {

        /**
         * Properties of a SoftwareUpdate.
         * @memberof hbb
         * @interface ISoftwareUpdate
         * @property {string|null} [url] SoftwareUpdate url
         */

        /**
         * Constructs a new SoftwareUpdate.
         * @memberof hbb
         * @classdesc Represents a SoftwareUpdate.
         * @implements ISoftwareUpdate
         * @constructor
         * @param {hbb.ISoftwareUpdate=} [properties] Properties to set
         */
        function SoftwareUpdate(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * SoftwareUpdate url.
         * @member {string} url
         * @memberof hbb.SoftwareUpdate
         * @instance
         */
        SoftwareUpdate.prototype.url = "";

        /**
         * Creates a new SoftwareUpdate instance using the specified properties.
         * @function create
         * @memberof hbb.SoftwareUpdate
         * @static
         * @param {hbb.ISoftwareUpdate=} [properties] Properties to set
         * @returns {hbb.SoftwareUpdate} SoftwareUpdate instance
         */
        SoftwareUpdate.create = function create(properties) {
            return new SoftwareUpdate(properties);
        };

        /**
         * Encodes the specified SoftwareUpdate message. Does not implicitly {@link hbb.SoftwareUpdate.verify|verify} messages.
         * @function encode
         * @memberof hbb.SoftwareUpdate
         * @static
         * @param {hbb.ISoftwareUpdate} message SoftwareUpdate message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SoftwareUpdate.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.url != null && Object.hasOwnProperty.call(message, "url"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.url);
            return writer;
        };

        /**
         * Encodes the specified SoftwareUpdate message, length delimited. Does not implicitly {@link hbb.SoftwareUpdate.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.SoftwareUpdate
         * @static
         * @param {hbb.ISoftwareUpdate} message SoftwareUpdate message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SoftwareUpdate.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a SoftwareUpdate message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.SoftwareUpdate
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.SoftwareUpdate} SoftwareUpdate
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SoftwareUpdate.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.SoftwareUpdate();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.url = reader.string();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a SoftwareUpdate message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.SoftwareUpdate
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.SoftwareUpdate} SoftwareUpdate
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SoftwareUpdate.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a SoftwareUpdate message.
         * @function verify
         * @memberof hbb.SoftwareUpdate
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        SoftwareUpdate.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.url != null && message.hasOwnProperty("url"))
                if (!$util.isString(message.url))
                    return "url: string expected";
            return null;
        };

        /**
         * Creates a SoftwareUpdate message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.SoftwareUpdate
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.SoftwareUpdate} SoftwareUpdate
         */
        SoftwareUpdate.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.SoftwareUpdate)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.SoftwareUpdate();
            if (object.url != null)
                message.url = String(object.url);
            return message;
        };

        /**
         * Creates a plain object from a SoftwareUpdate message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.SoftwareUpdate
         * @static
         * @param {hbb.SoftwareUpdate} message SoftwareUpdate
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        SoftwareUpdate.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults)
                object.url = "";
            if (message.url != null && message.hasOwnProperty("url"))
                object.url = message.url;
            return object;
        };

        /**
         * Converts this SoftwareUpdate to JSON.
         * @function toJSON
         * @memberof hbb.SoftwareUpdate
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        SoftwareUpdate.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for SoftwareUpdate
         * @function getTypeUrl
         * @memberof hbb.SoftwareUpdate
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        SoftwareUpdate.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.SoftwareUpdate";
        };

        return SoftwareUpdate;
    })();

    hbb.FetchLocalAddr = (function() {

        /**
         * Properties of a FetchLocalAddr.
         * @memberof hbb
         * @interface IFetchLocalAddr
         * @property {Uint8Array|null} [socket_addr] FetchLocalAddr socket_addr
         * @property {string|null} [relay_server] FetchLocalAddr relay_server
         */

        /**
         * Constructs a new FetchLocalAddr.
         * @memberof hbb
         * @classdesc Represents a FetchLocalAddr.
         * @implements IFetchLocalAddr
         * @constructor
         * @param {hbb.IFetchLocalAddr=} [properties] Properties to set
         */
        function FetchLocalAddr(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * FetchLocalAddr socket_addr.
         * @member {Uint8Array} socket_addr
         * @memberof hbb.FetchLocalAddr
         * @instance
         */
        FetchLocalAddr.prototype.socket_addr = $util.newBuffer([]);

        /**
         * FetchLocalAddr relay_server.
         * @member {string} relay_server
         * @memberof hbb.FetchLocalAddr
         * @instance
         */
        FetchLocalAddr.prototype.relay_server = "";

        /**
         * Creates a new FetchLocalAddr instance using the specified properties.
         * @function create
         * @memberof hbb.FetchLocalAddr
         * @static
         * @param {hbb.IFetchLocalAddr=} [properties] Properties to set
         * @returns {hbb.FetchLocalAddr} FetchLocalAddr instance
         */
        FetchLocalAddr.create = function create(properties) {
            return new FetchLocalAddr(properties);
        };

        /**
         * Encodes the specified FetchLocalAddr message. Does not implicitly {@link hbb.FetchLocalAddr.verify|verify} messages.
         * @function encode
         * @memberof hbb.FetchLocalAddr
         * @static
         * @param {hbb.IFetchLocalAddr} message FetchLocalAddr message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FetchLocalAddr.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.socket_addr != null && Object.hasOwnProperty.call(message, "socket_addr"))
                writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.socket_addr);
            if (message.relay_server != null && Object.hasOwnProperty.call(message, "relay_server"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.relay_server);
            return writer;
        };

        /**
         * Encodes the specified FetchLocalAddr message, length delimited. Does not implicitly {@link hbb.FetchLocalAddr.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.FetchLocalAddr
         * @static
         * @param {hbb.IFetchLocalAddr} message FetchLocalAddr message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FetchLocalAddr.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a FetchLocalAddr message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.FetchLocalAddr
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.FetchLocalAddr} FetchLocalAddr
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FetchLocalAddr.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.FetchLocalAddr();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.socket_addr = reader.bytes();
                        break;
                    }
                case 2: {
                        message.relay_server = reader.string();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a FetchLocalAddr message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.FetchLocalAddr
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.FetchLocalAddr} FetchLocalAddr
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FetchLocalAddr.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a FetchLocalAddr message.
         * @function verify
         * @memberof hbb.FetchLocalAddr
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        FetchLocalAddr.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.socket_addr != null && message.hasOwnProperty("socket_addr"))
                if (!(message.socket_addr && typeof message.socket_addr.length === "number" || $util.isString(message.socket_addr)))
                    return "socket_addr: buffer expected";
            if (message.relay_server != null && message.hasOwnProperty("relay_server"))
                if (!$util.isString(message.relay_server))
                    return "relay_server: string expected";
            return null;
        };

        /**
         * Creates a FetchLocalAddr message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.FetchLocalAddr
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.FetchLocalAddr} FetchLocalAddr
         */
        FetchLocalAddr.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.FetchLocalAddr)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.FetchLocalAddr();
            if (object.socket_addr != null)
                if (typeof object.socket_addr === "string")
                    $util.base64.decode(object.socket_addr, message.socket_addr = $util.newBuffer($util.base64.length(object.socket_addr)), 0);
                else if (object.socket_addr.length >= 0)
                    message.socket_addr = object.socket_addr;
            if (object.relay_server != null)
                message.relay_server = String(object.relay_server);
            return message;
        };

        /**
         * Creates a plain object from a FetchLocalAddr message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.FetchLocalAddr
         * @static
         * @param {hbb.FetchLocalAddr} message FetchLocalAddr
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        FetchLocalAddr.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                if (options.bytes === String)
                    object.socket_addr = "";
                else {
                    object.socket_addr = [];
                    if (options.bytes !== Array)
                        object.socket_addr = $util.newBuffer(object.socket_addr);
                }
                object.relay_server = "";
            }
            if (message.socket_addr != null && message.hasOwnProperty("socket_addr"))
                object.socket_addr = options.bytes === String ? $util.base64.encode(message.socket_addr, 0, message.socket_addr.length) : options.bytes === Array ? Array.prototype.slice.call(message.socket_addr) : message.socket_addr;
            if (message.relay_server != null && message.hasOwnProperty("relay_server"))
                object.relay_server = message.relay_server;
            return object;
        };

        /**
         * Converts this FetchLocalAddr to JSON.
         * @function toJSON
         * @memberof hbb.FetchLocalAddr
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        FetchLocalAddr.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for FetchLocalAddr
         * @function getTypeUrl
         * @memberof hbb.FetchLocalAddr
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        FetchLocalAddr.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.FetchLocalAddr";
        };

        return FetchLocalAddr;
    })();

    hbb.LocalAddr = (function() {

        /**
         * Properties of a LocalAddr.
         * @memberof hbb
         * @interface ILocalAddr
         * @property {Uint8Array|null} [socket_addr] LocalAddr socket_addr
         * @property {Uint8Array|null} [local_addr] LocalAddr local_addr
         * @property {string|null} [relay_server] LocalAddr relay_server
         * @property {string|null} [id] LocalAddr id
         * @property {string|null} [version] LocalAddr version
         */

        /**
         * Constructs a new LocalAddr.
         * @memberof hbb
         * @classdesc Represents a LocalAddr.
         * @implements ILocalAddr
         * @constructor
         * @param {hbb.ILocalAddr=} [properties] Properties to set
         */
        function LocalAddr(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * LocalAddr socket_addr.
         * @member {Uint8Array} socket_addr
         * @memberof hbb.LocalAddr
         * @instance
         */
        LocalAddr.prototype.socket_addr = $util.newBuffer([]);

        /**
         * LocalAddr local_addr.
         * @member {Uint8Array} local_addr
         * @memberof hbb.LocalAddr
         * @instance
         */
        LocalAddr.prototype.local_addr = $util.newBuffer([]);

        /**
         * LocalAddr relay_server.
         * @member {string} relay_server
         * @memberof hbb.LocalAddr
         * @instance
         */
        LocalAddr.prototype.relay_server = "";

        /**
         * LocalAddr id.
         * @member {string} id
         * @memberof hbb.LocalAddr
         * @instance
         */
        LocalAddr.prototype.id = "";

        /**
         * LocalAddr version.
         * @member {string} version
         * @memberof hbb.LocalAddr
         * @instance
         */
        LocalAddr.prototype.version = "";

        /**
         * Creates a new LocalAddr instance using the specified properties.
         * @function create
         * @memberof hbb.LocalAddr
         * @static
         * @param {hbb.ILocalAddr=} [properties] Properties to set
         * @returns {hbb.LocalAddr} LocalAddr instance
         */
        LocalAddr.create = function create(properties) {
            return new LocalAddr(properties);
        };

        /**
         * Encodes the specified LocalAddr message. Does not implicitly {@link hbb.LocalAddr.verify|verify} messages.
         * @function encode
         * @memberof hbb.LocalAddr
         * @static
         * @param {hbb.ILocalAddr} message LocalAddr message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        LocalAddr.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.socket_addr != null && Object.hasOwnProperty.call(message, "socket_addr"))
                writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.socket_addr);
            if (message.local_addr != null && Object.hasOwnProperty.call(message, "local_addr"))
                writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.local_addr);
            if (message.relay_server != null && Object.hasOwnProperty.call(message, "relay_server"))
                writer.uint32(/* id 3, wireType 2 =*/26).string(message.relay_server);
            if (message.id != null && Object.hasOwnProperty.call(message, "id"))
                writer.uint32(/* id 4, wireType 2 =*/34).string(message.id);
            if (message.version != null && Object.hasOwnProperty.call(message, "version"))
                writer.uint32(/* id 5, wireType 2 =*/42).string(message.version);
            return writer;
        };

        /**
         * Encodes the specified LocalAddr message, length delimited. Does not implicitly {@link hbb.LocalAddr.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.LocalAddr
         * @static
         * @param {hbb.ILocalAddr} message LocalAddr message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        LocalAddr.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a LocalAddr message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.LocalAddr
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.LocalAddr} LocalAddr
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        LocalAddr.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.LocalAddr();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.socket_addr = reader.bytes();
                        break;
                    }
                case 2: {
                        message.local_addr = reader.bytes();
                        break;
                    }
                case 3: {
                        message.relay_server = reader.string();
                        break;
                    }
                case 4: {
                        message.id = reader.string();
                        break;
                    }
                case 5: {
                        message.version = reader.string();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a LocalAddr message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.LocalAddr
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.LocalAddr} LocalAddr
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        LocalAddr.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a LocalAddr message.
         * @function verify
         * @memberof hbb.LocalAddr
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        LocalAddr.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.socket_addr != null && message.hasOwnProperty("socket_addr"))
                if (!(message.socket_addr && typeof message.socket_addr.length === "number" || $util.isString(message.socket_addr)))
                    return "socket_addr: buffer expected";
            if (message.local_addr != null && message.hasOwnProperty("local_addr"))
                if (!(message.local_addr && typeof message.local_addr.length === "number" || $util.isString(message.local_addr)))
                    return "local_addr: buffer expected";
            if (message.relay_server != null && message.hasOwnProperty("relay_server"))
                if (!$util.isString(message.relay_server))
                    return "relay_server: string expected";
            if (message.id != null && message.hasOwnProperty("id"))
                if (!$util.isString(message.id))
                    return "id: string expected";
            if (message.version != null && message.hasOwnProperty("version"))
                if (!$util.isString(message.version))
                    return "version: string expected";
            return null;
        };

        /**
         * Creates a LocalAddr message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.LocalAddr
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.LocalAddr} LocalAddr
         */
        LocalAddr.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.LocalAddr)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.LocalAddr();
            if (object.socket_addr != null)
                if (typeof object.socket_addr === "string")
                    $util.base64.decode(object.socket_addr, message.socket_addr = $util.newBuffer($util.base64.length(object.socket_addr)), 0);
                else if (object.socket_addr.length >= 0)
                    message.socket_addr = object.socket_addr;
            if (object.local_addr != null)
                if (typeof object.local_addr === "string")
                    $util.base64.decode(object.local_addr, message.local_addr = $util.newBuffer($util.base64.length(object.local_addr)), 0);
                else if (object.local_addr.length >= 0)
                    message.local_addr = object.local_addr;
            if (object.relay_server != null)
                message.relay_server = String(object.relay_server);
            if (object.id != null)
                message.id = String(object.id);
            if (object.version != null)
                message.version = String(object.version);
            return message;
        };

        /**
         * Creates a plain object from a LocalAddr message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.LocalAddr
         * @static
         * @param {hbb.LocalAddr} message LocalAddr
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        LocalAddr.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                if (options.bytes === String)
                    object.socket_addr = "";
                else {
                    object.socket_addr = [];
                    if (options.bytes !== Array)
                        object.socket_addr = $util.newBuffer(object.socket_addr);
                }
                if (options.bytes === String)
                    object.local_addr = "";
                else {
                    object.local_addr = [];
                    if (options.bytes !== Array)
                        object.local_addr = $util.newBuffer(object.local_addr);
                }
                object.relay_server = "";
                object.id = "";
                object.version = "";
            }
            if (message.socket_addr != null && message.hasOwnProperty("socket_addr"))
                object.socket_addr = options.bytes === String ? $util.base64.encode(message.socket_addr, 0, message.socket_addr.length) : options.bytes === Array ? Array.prototype.slice.call(message.socket_addr) : message.socket_addr;
            if (message.local_addr != null && message.hasOwnProperty("local_addr"))
                object.local_addr = options.bytes === String ? $util.base64.encode(message.local_addr, 0, message.local_addr.length) : options.bytes === Array ? Array.prototype.slice.call(message.local_addr) : message.local_addr;
            if (message.relay_server != null && message.hasOwnProperty("relay_server"))
                object.relay_server = message.relay_server;
            if (message.id != null && message.hasOwnProperty("id"))
                object.id = message.id;
            if (message.version != null && message.hasOwnProperty("version"))
                object.version = message.version;
            return object;
        };

        /**
         * Converts this LocalAddr to JSON.
         * @function toJSON
         * @memberof hbb.LocalAddr
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        LocalAddr.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for LocalAddr
         * @function getTypeUrl
         * @memberof hbb.LocalAddr
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        LocalAddr.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.LocalAddr";
        };

        return LocalAddr;
    })();

    hbb.PeerDiscovery = (function() {

        /**
         * Properties of a PeerDiscovery.
         * @memberof hbb
         * @interface IPeerDiscovery
         * @property {string|null} [cmd] PeerDiscovery cmd
         * @property {string|null} [mac] PeerDiscovery mac
         * @property {string|null} [id] PeerDiscovery id
         * @property {string|null} [username] PeerDiscovery username
         * @property {string|null} [hostname] PeerDiscovery hostname
         * @property {string|null} [platform] PeerDiscovery platform
         * @property {string|null} [misc] PeerDiscovery misc
         */

        /**
         * Constructs a new PeerDiscovery.
         * @memberof hbb
         * @classdesc Represents a PeerDiscovery.
         * @implements IPeerDiscovery
         * @constructor
         * @param {hbb.IPeerDiscovery=} [properties] Properties to set
         */
        function PeerDiscovery(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * PeerDiscovery cmd.
         * @member {string} cmd
         * @memberof hbb.PeerDiscovery
         * @instance
         */
        PeerDiscovery.prototype.cmd = "";

        /**
         * PeerDiscovery mac.
         * @member {string} mac
         * @memberof hbb.PeerDiscovery
         * @instance
         */
        PeerDiscovery.prototype.mac = "";

        /**
         * PeerDiscovery id.
         * @member {string} id
         * @memberof hbb.PeerDiscovery
         * @instance
         */
        PeerDiscovery.prototype.id = "";

        /**
         * PeerDiscovery username.
         * @member {string} username
         * @memberof hbb.PeerDiscovery
         * @instance
         */
        PeerDiscovery.prototype.username = "";

        /**
         * PeerDiscovery hostname.
         * @member {string} hostname
         * @memberof hbb.PeerDiscovery
         * @instance
         */
        PeerDiscovery.prototype.hostname = "";

        /**
         * PeerDiscovery platform.
         * @member {string} platform
         * @memberof hbb.PeerDiscovery
         * @instance
         */
        PeerDiscovery.prototype.platform = "";

        /**
         * PeerDiscovery misc.
         * @member {string} misc
         * @memberof hbb.PeerDiscovery
         * @instance
         */
        PeerDiscovery.prototype.misc = "";

        /**
         * Creates a new PeerDiscovery instance using the specified properties.
         * @function create
         * @memberof hbb.PeerDiscovery
         * @static
         * @param {hbb.IPeerDiscovery=} [properties] Properties to set
         * @returns {hbb.PeerDiscovery} PeerDiscovery instance
         */
        PeerDiscovery.create = function create(properties) {
            return new PeerDiscovery(properties);
        };

        /**
         * Encodes the specified PeerDiscovery message. Does not implicitly {@link hbb.PeerDiscovery.verify|verify} messages.
         * @function encode
         * @memberof hbb.PeerDiscovery
         * @static
         * @param {hbb.IPeerDiscovery} message PeerDiscovery message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        PeerDiscovery.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.cmd != null && Object.hasOwnProperty.call(message, "cmd"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.cmd);
            if (message.mac != null && Object.hasOwnProperty.call(message, "mac"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.mac);
            if (message.id != null && Object.hasOwnProperty.call(message, "id"))
                writer.uint32(/* id 3, wireType 2 =*/26).string(message.id);
            if (message.username != null && Object.hasOwnProperty.call(message, "username"))
                writer.uint32(/* id 4, wireType 2 =*/34).string(message.username);
            if (message.hostname != null && Object.hasOwnProperty.call(message, "hostname"))
                writer.uint32(/* id 5, wireType 2 =*/42).string(message.hostname);
            if (message.platform != null && Object.hasOwnProperty.call(message, "platform"))
                writer.uint32(/* id 6, wireType 2 =*/50).string(message.platform);
            if (message.misc != null && Object.hasOwnProperty.call(message, "misc"))
                writer.uint32(/* id 7, wireType 2 =*/58).string(message.misc);
            return writer;
        };

        /**
         * Encodes the specified PeerDiscovery message, length delimited. Does not implicitly {@link hbb.PeerDiscovery.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.PeerDiscovery
         * @static
         * @param {hbb.IPeerDiscovery} message PeerDiscovery message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        PeerDiscovery.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a PeerDiscovery message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.PeerDiscovery
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.PeerDiscovery} PeerDiscovery
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        PeerDiscovery.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.PeerDiscovery();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.cmd = reader.string();
                        break;
                    }
                case 2: {
                        message.mac = reader.string();
                        break;
                    }
                case 3: {
                        message.id = reader.string();
                        break;
                    }
                case 4: {
                        message.username = reader.string();
                        break;
                    }
                case 5: {
                        message.hostname = reader.string();
                        break;
                    }
                case 6: {
                        message.platform = reader.string();
                        break;
                    }
                case 7: {
                        message.misc = reader.string();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a PeerDiscovery message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.PeerDiscovery
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.PeerDiscovery} PeerDiscovery
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        PeerDiscovery.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a PeerDiscovery message.
         * @function verify
         * @memberof hbb.PeerDiscovery
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        PeerDiscovery.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.cmd != null && message.hasOwnProperty("cmd"))
                if (!$util.isString(message.cmd))
                    return "cmd: string expected";
            if (message.mac != null && message.hasOwnProperty("mac"))
                if (!$util.isString(message.mac))
                    return "mac: string expected";
            if (message.id != null && message.hasOwnProperty("id"))
                if (!$util.isString(message.id))
                    return "id: string expected";
            if (message.username != null && message.hasOwnProperty("username"))
                if (!$util.isString(message.username))
                    return "username: string expected";
            if (message.hostname != null && message.hasOwnProperty("hostname"))
                if (!$util.isString(message.hostname))
                    return "hostname: string expected";
            if (message.platform != null && message.hasOwnProperty("platform"))
                if (!$util.isString(message.platform))
                    return "platform: string expected";
            if (message.misc != null && message.hasOwnProperty("misc"))
                if (!$util.isString(message.misc))
                    return "misc: string expected";
            return null;
        };

        /**
         * Creates a PeerDiscovery message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.PeerDiscovery
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.PeerDiscovery} PeerDiscovery
         */
        PeerDiscovery.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.PeerDiscovery)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.PeerDiscovery();
            if (object.cmd != null)
                message.cmd = String(object.cmd);
            if (object.mac != null)
                message.mac = String(object.mac);
            if (object.id != null)
                message.id = String(object.id);
            if (object.username != null)
                message.username = String(object.username);
            if (object.hostname != null)
                message.hostname = String(object.hostname);
            if (object.platform != null)
                message.platform = String(object.platform);
            if (object.misc != null)
                message.misc = String(object.misc);
            return message;
        };

        /**
         * Creates a plain object from a PeerDiscovery message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.PeerDiscovery
         * @static
         * @param {hbb.PeerDiscovery} message PeerDiscovery
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        PeerDiscovery.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.cmd = "";
                object.mac = "";
                object.id = "";
                object.username = "";
                object.hostname = "";
                object.platform = "";
                object.misc = "";
            }
            if (message.cmd != null && message.hasOwnProperty("cmd"))
                object.cmd = message.cmd;
            if (message.mac != null && message.hasOwnProperty("mac"))
                object.mac = message.mac;
            if (message.id != null && message.hasOwnProperty("id"))
                object.id = message.id;
            if (message.username != null && message.hasOwnProperty("username"))
                object.username = message.username;
            if (message.hostname != null && message.hasOwnProperty("hostname"))
                object.hostname = message.hostname;
            if (message.platform != null && message.hasOwnProperty("platform"))
                object.platform = message.platform;
            if (message.misc != null && message.hasOwnProperty("misc"))
                object.misc = message.misc;
            return object;
        };

        /**
         * Converts this PeerDiscovery to JSON.
         * @function toJSON
         * @memberof hbb.PeerDiscovery
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        PeerDiscovery.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for PeerDiscovery
         * @function getTypeUrl
         * @memberof hbb.PeerDiscovery
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        PeerDiscovery.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.PeerDiscovery";
        };

        return PeerDiscovery;
    })();

    hbb.OnlineRequest = (function() {

        /**
         * Properties of an OnlineRequest.
         * @memberof hbb
         * @interface IOnlineRequest
         * @property {string|null} [id] OnlineRequest id
         * @property {Array.<string>|null} [peers] OnlineRequest peers
         */

        /**
         * Constructs a new OnlineRequest.
         * @memberof hbb
         * @classdesc Represents an OnlineRequest.
         * @implements IOnlineRequest
         * @constructor
         * @param {hbb.IOnlineRequest=} [properties] Properties to set
         */
        function OnlineRequest(properties) {
            this.peers = [];
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * OnlineRequest id.
         * @member {string} id
         * @memberof hbb.OnlineRequest
         * @instance
         */
        OnlineRequest.prototype.id = "";

        /**
         * OnlineRequest peers.
         * @member {Array.<string>} peers
         * @memberof hbb.OnlineRequest
         * @instance
         */
        OnlineRequest.prototype.peers = $util.emptyArray;

        /**
         * Creates a new OnlineRequest instance using the specified properties.
         * @function create
         * @memberof hbb.OnlineRequest
         * @static
         * @param {hbb.IOnlineRequest=} [properties] Properties to set
         * @returns {hbb.OnlineRequest} OnlineRequest instance
         */
        OnlineRequest.create = function create(properties) {
            return new OnlineRequest(properties);
        };

        /**
         * Encodes the specified OnlineRequest message. Does not implicitly {@link hbb.OnlineRequest.verify|verify} messages.
         * @function encode
         * @memberof hbb.OnlineRequest
         * @static
         * @param {hbb.IOnlineRequest} message OnlineRequest message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        OnlineRequest.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.id != null && Object.hasOwnProperty.call(message, "id"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.id);
            if (message.peers != null && message.peers.length)
                for (let i = 0; i < message.peers.length; ++i)
                    writer.uint32(/* id 2, wireType 2 =*/18).string(message.peers[i]);
            return writer;
        };

        /**
         * Encodes the specified OnlineRequest message, length delimited. Does not implicitly {@link hbb.OnlineRequest.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.OnlineRequest
         * @static
         * @param {hbb.IOnlineRequest} message OnlineRequest message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        OnlineRequest.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an OnlineRequest message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.OnlineRequest
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.OnlineRequest} OnlineRequest
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        OnlineRequest.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.OnlineRequest();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.id = reader.string();
                        break;
                    }
                case 2: {
                        if (!(message.peers && message.peers.length))
                            message.peers = [];
                        message.peers.push(reader.string());
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an OnlineRequest message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.OnlineRequest
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.OnlineRequest} OnlineRequest
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        OnlineRequest.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an OnlineRequest message.
         * @function verify
         * @memberof hbb.OnlineRequest
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        OnlineRequest.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.id != null && message.hasOwnProperty("id"))
                if (!$util.isString(message.id))
                    return "id: string expected";
            if (message.peers != null && message.hasOwnProperty("peers")) {
                if (!Array.isArray(message.peers))
                    return "peers: array expected";
                for (let i = 0; i < message.peers.length; ++i)
                    if (!$util.isString(message.peers[i]))
                        return "peers: string[] expected";
            }
            return null;
        };

        /**
         * Creates an OnlineRequest message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.OnlineRequest
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.OnlineRequest} OnlineRequest
         */
        OnlineRequest.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.OnlineRequest)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.OnlineRequest();
            if (object.id != null)
                message.id = String(object.id);
            if (object.peers) {
                if (!Array.isArray(object.peers))
                    throw TypeError(".hbb.OnlineRequest.peers: array expected");
                message.peers = [];
                for (let i = 0; i < object.peers.length; ++i)
                    message.peers[i] = String(object.peers[i]);
            }
            return message;
        };

        /**
         * Creates a plain object from an OnlineRequest message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.OnlineRequest
         * @static
         * @param {hbb.OnlineRequest} message OnlineRequest
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        OnlineRequest.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.arrays || options.defaults)
                object.peers = [];
            if (options.defaults)
                object.id = "";
            if (message.id != null && message.hasOwnProperty("id"))
                object.id = message.id;
            if (message.peers && message.peers.length) {
                object.peers = [];
                for (let j = 0; j < message.peers.length; ++j)
                    object.peers[j] = message.peers[j];
            }
            return object;
        };

        /**
         * Converts this OnlineRequest to JSON.
         * @function toJSON
         * @memberof hbb.OnlineRequest
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        OnlineRequest.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for OnlineRequest
         * @function getTypeUrl
         * @memberof hbb.OnlineRequest
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        OnlineRequest.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.OnlineRequest";
        };

        return OnlineRequest;
    })();

    hbb.OnlineResponse = (function() {

        /**
         * Properties of an OnlineResponse.
         * @memberof hbb
         * @interface IOnlineResponse
         * @property {Uint8Array|null} [states] OnlineResponse states
         */

        /**
         * Constructs a new OnlineResponse.
         * @memberof hbb
         * @classdesc Represents an OnlineResponse.
         * @implements IOnlineResponse
         * @constructor
         * @param {hbb.IOnlineResponse=} [properties] Properties to set
         */
        function OnlineResponse(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * OnlineResponse states.
         * @member {Uint8Array} states
         * @memberof hbb.OnlineResponse
         * @instance
         */
        OnlineResponse.prototype.states = $util.newBuffer([]);

        /**
         * Creates a new OnlineResponse instance using the specified properties.
         * @function create
         * @memberof hbb.OnlineResponse
         * @static
         * @param {hbb.IOnlineResponse=} [properties] Properties to set
         * @returns {hbb.OnlineResponse} OnlineResponse instance
         */
        OnlineResponse.create = function create(properties) {
            return new OnlineResponse(properties);
        };

        /**
         * Encodes the specified OnlineResponse message. Does not implicitly {@link hbb.OnlineResponse.verify|verify} messages.
         * @function encode
         * @memberof hbb.OnlineResponse
         * @static
         * @param {hbb.IOnlineResponse} message OnlineResponse message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        OnlineResponse.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.states != null && Object.hasOwnProperty.call(message, "states"))
                writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.states);
            return writer;
        };

        /**
         * Encodes the specified OnlineResponse message, length delimited. Does not implicitly {@link hbb.OnlineResponse.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.OnlineResponse
         * @static
         * @param {hbb.IOnlineResponse} message OnlineResponse message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        OnlineResponse.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an OnlineResponse message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.OnlineResponse
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.OnlineResponse} OnlineResponse
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        OnlineResponse.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.OnlineResponse();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.states = reader.bytes();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an OnlineResponse message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.OnlineResponse
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.OnlineResponse} OnlineResponse
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        OnlineResponse.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an OnlineResponse message.
         * @function verify
         * @memberof hbb.OnlineResponse
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        OnlineResponse.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.states != null && message.hasOwnProperty("states"))
                if (!(message.states && typeof message.states.length === "number" || $util.isString(message.states)))
                    return "states: buffer expected";
            return null;
        };

        /**
         * Creates an OnlineResponse message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.OnlineResponse
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.OnlineResponse} OnlineResponse
         */
        OnlineResponse.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.OnlineResponse)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.OnlineResponse();
            if (object.states != null)
                if (typeof object.states === "string")
                    $util.base64.decode(object.states, message.states = $util.newBuffer($util.base64.length(object.states)), 0);
                else if (object.states.length >= 0)
                    message.states = object.states;
            return message;
        };

        /**
         * Creates a plain object from an OnlineResponse message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.OnlineResponse
         * @static
         * @param {hbb.OnlineResponse} message OnlineResponse
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        OnlineResponse.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults)
                if (options.bytes === String)
                    object.states = "";
                else {
                    object.states = [];
                    if (options.bytes !== Array)
                        object.states = $util.newBuffer(object.states);
                }
            if (message.states != null && message.hasOwnProperty("states"))
                object.states = options.bytes === String ? $util.base64.encode(message.states, 0, message.states.length) : options.bytes === Array ? Array.prototype.slice.call(message.states) : message.states;
            return object;
        };

        /**
         * Converts this OnlineResponse to JSON.
         * @function toJSON
         * @memberof hbb.OnlineResponse
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        OnlineResponse.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for OnlineResponse
         * @function getTypeUrl
         * @memberof hbb.OnlineResponse
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        OnlineResponse.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.OnlineResponse";
        };

        return OnlineResponse;
    })();

    hbb.KeyExchange = (function() {

        /**
         * Properties of a KeyExchange.
         * @memberof hbb
         * @interface IKeyExchange
         * @property {Array.<Uint8Array>|null} [keys] KeyExchange keys
         */

        /**
         * Constructs a new KeyExchange.
         * @memberof hbb
         * @classdesc Represents a KeyExchange.
         * @implements IKeyExchange
         * @constructor
         * @param {hbb.IKeyExchange=} [properties] Properties to set
         */
        function KeyExchange(properties) {
            this.keys = [];
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * KeyExchange keys.
         * @member {Array.<Uint8Array>} keys
         * @memberof hbb.KeyExchange
         * @instance
         */
        KeyExchange.prototype.keys = $util.emptyArray;

        /**
         * Creates a new KeyExchange instance using the specified properties.
         * @function create
         * @memberof hbb.KeyExchange
         * @static
         * @param {hbb.IKeyExchange=} [properties] Properties to set
         * @returns {hbb.KeyExchange} KeyExchange instance
         */
        KeyExchange.create = function create(properties) {
            return new KeyExchange(properties);
        };

        /**
         * Encodes the specified KeyExchange message. Does not implicitly {@link hbb.KeyExchange.verify|verify} messages.
         * @function encode
         * @memberof hbb.KeyExchange
         * @static
         * @param {hbb.IKeyExchange} message KeyExchange message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        KeyExchange.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.keys != null && message.keys.length)
                for (let i = 0; i < message.keys.length; ++i)
                    writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.keys[i]);
            return writer;
        };

        /**
         * Encodes the specified KeyExchange message, length delimited. Does not implicitly {@link hbb.KeyExchange.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.KeyExchange
         * @static
         * @param {hbb.IKeyExchange} message KeyExchange message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        KeyExchange.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a KeyExchange message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.KeyExchange
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.KeyExchange} KeyExchange
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        KeyExchange.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.KeyExchange();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        if (!(message.keys && message.keys.length))
                            message.keys = [];
                        message.keys.push(reader.bytes());
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a KeyExchange message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.KeyExchange
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.KeyExchange} KeyExchange
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        KeyExchange.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a KeyExchange message.
         * @function verify
         * @memberof hbb.KeyExchange
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        KeyExchange.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.keys != null && message.hasOwnProperty("keys")) {
                if (!Array.isArray(message.keys))
                    return "keys: array expected";
                for (let i = 0; i < message.keys.length; ++i)
                    if (!(message.keys[i] && typeof message.keys[i].length === "number" || $util.isString(message.keys[i])))
                        return "keys: buffer[] expected";
            }
            return null;
        };

        /**
         * Creates a KeyExchange message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.KeyExchange
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.KeyExchange} KeyExchange
         */
        KeyExchange.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.KeyExchange)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.KeyExchange();
            if (object.keys) {
                if (!Array.isArray(object.keys))
                    throw TypeError(".hbb.KeyExchange.keys: array expected");
                message.keys = [];
                for (let i = 0; i < object.keys.length; ++i)
                    if (typeof object.keys[i] === "string")
                        $util.base64.decode(object.keys[i], message.keys[i] = $util.newBuffer($util.base64.length(object.keys[i])), 0);
                    else if (object.keys[i].length >= 0)
                        message.keys[i] = object.keys[i];
            }
            return message;
        };

        /**
         * Creates a plain object from a KeyExchange message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.KeyExchange
         * @static
         * @param {hbb.KeyExchange} message KeyExchange
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        KeyExchange.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.arrays || options.defaults)
                object.keys = [];
            if (message.keys && message.keys.length) {
                object.keys = [];
                for (let j = 0; j < message.keys.length; ++j)
                    object.keys[j] = options.bytes === String ? $util.base64.encode(message.keys[j], 0, message.keys[j].length) : options.bytes === Array ? Array.prototype.slice.call(message.keys[j]) : message.keys[j];
            }
            return object;
        };

        /**
         * Converts this KeyExchange to JSON.
         * @function toJSON
         * @memberof hbb.KeyExchange
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        KeyExchange.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for KeyExchange
         * @function getTypeUrl
         * @memberof hbb.KeyExchange
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        KeyExchange.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.KeyExchange";
        };

        return KeyExchange;
    })();

    hbb.HealthCheck = (function() {

        /**
         * Properties of a HealthCheck.
         * @memberof hbb
         * @interface IHealthCheck
         * @property {string|null} [token] HealthCheck token
         */

        /**
         * Constructs a new HealthCheck.
         * @memberof hbb
         * @classdesc Represents a HealthCheck.
         * @implements IHealthCheck
         * @constructor
         * @param {hbb.IHealthCheck=} [properties] Properties to set
         */
        function HealthCheck(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * HealthCheck token.
         * @member {string} token
         * @memberof hbb.HealthCheck
         * @instance
         */
        HealthCheck.prototype.token = "";

        /**
         * Creates a new HealthCheck instance using the specified properties.
         * @function create
         * @memberof hbb.HealthCheck
         * @static
         * @param {hbb.IHealthCheck=} [properties] Properties to set
         * @returns {hbb.HealthCheck} HealthCheck instance
         */
        HealthCheck.create = function create(properties) {
            return new HealthCheck(properties);
        };

        /**
         * Encodes the specified HealthCheck message. Does not implicitly {@link hbb.HealthCheck.verify|verify} messages.
         * @function encode
         * @memberof hbb.HealthCheck
         * @static
         * @param {hbb.IHealthCheck} message HealthCheck message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        HealthCheck.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.token != null && Object.hasOwnProperty.call(message, "token"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.token);
            return writer;
        };

        /**
         * Encodes the specified HealthCheck message, length delimited. Does not implicitly {@link hbb.HealthCheck.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.HealthCheck
         * @static
         * @param {hbb.IHealthCheck} message HealthCheck message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        HealthCheck.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a HealthCheck message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.HealthCheck
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.HealthCheck} HealthCheck
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        HealthCheck.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.HealthCheck();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.token = reader.string();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a HealthCheck message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.HealthCheck
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.HealthCheck} HealthCheck
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        HealthCheck.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a HealthCheck message.
         * @function verify
         * @memberof hbb.HealthCheck
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        HealthCheck.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.token != null && message.hasOwnProperty("token"))
                if (!$util.isString(message.token))
                    return "token: string expected";
            return null;
        };

        /**
         * Creates a HealthCheck message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.HealthCheck
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.HealthCheck} HealthCheck
         */
        HealthCheck.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.HealthCheck)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.HealthCheck();
            if (object.token != null)
                message.token = String(object.token);
            return message;
        };

        /**
         * Creates a plain object from a HealthCheck message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.HealthCheck
         * @static
         * @param {hbb.HealthCheck} message HealthCheck
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        HealthCheck.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults)
                object.token = "";
            if (message.token != null && message.hasOwnProperty("token"))
                object.token = message.token;
            return object;
        };

        /**
         * Converts this HealthCheck to JSON.
         * @function toJSON
         * @memberof hbb.HealthCheck
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        HealthCheck.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for HealthCheck
         * @function getTypeUrl
         * @memberof hbb.HealthCheck
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        HealthCheck.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.HealthCheck";
        };

        return HealthCheck;
    })();

    hbb.HeaderEntry = (function() {

        /**
         * Properties of a HeaderEntry.
         * @memberof hbb
         * @interface IHeaderEntry
         * @property {string|null} [name] HeaderEntry name
         * @property {string|null} [value] HeaderEntry value
         */

        /**
         * Constructs a new HeaderEntry.
         * @memberof hbb
         * @classdesc Represents a HeaderEntry.
         * @implements IHeaderEntry
         * @constructor
         * @param {hbb.IHeaderEntry=} [properties] Properties to set
         */
        function HeaderEntry(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * HeaderEntry name.
         * @member {string} name
         * @memberof hbb.HeaderEntry
         * @instance
         */
        HeaderEntry.prototype.name = "";

        /**
         * HeaderEntry value.
         * @member {string} value
         * @memberof hbb.HeaderEntry
         * @instance
         */
        HeaderEntry.prototype.value = "";

        /**
         * Creates a new HeaderEntry instance using the specified properties.
         * @function create
         * @memberof hbb.HeaderEntry
         * @static
         * @param {hbb.IHeaderEntry=} [properties] Properties to set
         * @returns {hbb.HeaderEntry} HeaderEntry instance
         */
        HeaderEntry.create = function create(properties) {
            return new HeaderEntry(properties);
        };

        /**
         * Encodes the specified HeaderEntry message. Does not implicitly {@link hbb.HeaderEntry.verify|verify} messages.
         * @function encode
         * @memberof hbb.HeaderEntry
         * @static
         * @param {hbb.IHeaderEntry} message HeaderEntry message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        HeaderEntry.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.name != null && Object.hasOwnProperty.call(message, "name"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.name);
            if (message.value != null && Object.hasOwnProperty.call(message, "value"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.value);
            return writer;
        };

        /**
         * Encodes the specified HeaderEntry message, length delimited. Does not implicitly {@link hbb.HeaderEntry.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.HeaderEntry
         * @static
         * @param {hbb.IHeaderEntry} message HeaderEntry message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        HeaderEntry.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a HeaderEntry message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.HeaderEntry
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.HeaderEntry} HeaderEntry
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        HeaderEntry.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.HeaderEntry();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.name = reader.string();
                        break;
                    }
                case 2: {
                        message.value = reader.string();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a HeaderEntry message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.HeaderEntry
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.HeaderEntry} HeaderEntry
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        HeaderEntry.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a HeaderEntry message.
         * @function verify
         * @memberof hbb.HeaderEntry
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        HeaderEntry.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.name != null && message.hasOwnProperty("name"))
                if (!$util.isString(message.name))
                    return "name: string expected";
            if (message.value != null && message.hasOwnProperty("value"))
                if (!$util.isString(message.value))
                    return "value: string expected";
            return null;
        };

        /**
         * Creates a HeaderEntry message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.HeaderEntry
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.HeaderEntry} HeaderEntry
         */
        HeaderEntry.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.HeaderEntry)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.HeaderEntry();
            if (object.name != null)
                message.name = String(object.name);
            if (object.value != null)
                message.value = String(object.value);
            return message;
        };

        /**
         * Creates a plain object from a HeaderEntry message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.HeaderEntry
         * @static
         * @param {hbb.HeaderEntry} message HeaderEntry
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        HeaderEntry.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.name = "";
                object.value = "";
            }
            if (message.name != null && message.hasOwnProperty("name"))
                object.name = message.name;
            if (message.value != null && message.hasOwnProperty("value"))
                object.value = message.value;
            return object;
        };

        /**
         * Converts this HeaderEntry to JSON.
         * @function toJSON
         * @memberof hbb.HeaderEntry
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        HeaderEntry.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for HeaderEntry
         * @function getTypeUrl
         * @memberof hbb.HeaderEntry
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        HeaderEntry.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.HeaderEntry";
        };

        return HeaderEntry;
    })();

    hbb.HttpProxyRequest = (function() {

        /**
         * Properties of a HttpProxyRequest.
         * @memberof hbb
         * @interface IHttpProxyRequest
         * @property {string|null} [method] HttpProxyRequest method
         * @property {string|null} [path] HttpProxyRequest path
         * @property {Array.<hbb.IHeaderEntry>|null} [headers] HttpProxyRequest headers
         * @property {Uint8Array|null} [body] HttpProxyRequest body
         */

        /**
         * Constructs a new HttpProxyRequest.
         * @memberof hbb
         * @classdesc Represents a HttpProxyRequest.
         * @implements IHttpProxyRequest
         * @constructor
         * @param {hbb.IHttpProxyRequest=} [properties] Properties to set
         */
        function HttpProxyRequest(properties) {
            this.headers = [];
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * HttpProxyRequest method.
         * @member {string} method
         * @memberof hbb.HttpProxyRequest
         * @instance
         */
        HttpProxyRequest.prototype.method = "";

        /**
         * HttpProxyRequest path.
         * @member {string} path
         * @memberof hbb.HttpProxyRequest
         * @instance
         */
        HttpProxyRequest.prototype.path = "";

        /**
         * HttpProxyRequest headers.
         * @member {Array.<hbb.IHeaderEntry>} headers
         * @memberof hbb.HttpProxyRequest
         * @instance
         */
        HttpProxyRequest.prototype.headers = $util.emptyArray;

        /**
         * HttpProxyRequest body.
         * @member {Uint8Array} body
         * @memberof hbb.HttpProxyRequest
         * @instance
         */
        HttpProxyRequest.prototype.body = $util.newBuffer([]);

        /**
         * Creates a new HttpProxyRequest instance using the specified properties.
         * @function create
         * @memberof hbb.HttpProxyRequest
         * @static
         * @param {hbb.IHttpProxyRequest=} [properties] Properties to set
         * @returns {hbb.HttpProxyRequest} HttpProxyRequest instance
         */
        HttpProxyRequest.create = function create(properties) {
            return new HttpProxyRequest(properties);
        };

        /**
         * Encodes the specified HttpProxyRequest message. Does not implicitly {@link hbb.HttpProxyRequest.verify|verify} messages.
         * @function encode
         * @memberof hbb.HttpProxyRequest
         * @static
         * @param {hbb.IHttpProxyRequest} message HttpProxyRequest message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        HttpProxyRequest.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.method != null && Object.hasOwnProperty.call(message, "method"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.method);
            if (message.path != null && Object.hasOwnProperty.call(message, "path"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.path);
            if (message.headers != null && message.headers.length)
                for (let i = 0; i < message.headers.length; ++i)
                    $root.hbb.HeaderEntry.encode(message.headers[i], writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
            if (message.body != null && Object.hasOwnProperty.call(message, "body"))
                writer.uint32(/* id 4, wireType 2 =*/34).bytes(message.body);
            return writer;
        };

        /**
         * Encodes the specified HttpProxyRequest message, length delimited. Does not implicitly {@link hbb.HttpProxyRequest.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.HttpProxyRequest
         * @static
         * @param {hbb.IHttpProxyRequest} message HttpProxyRequest message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        HttpProxyRequest.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a HttpProxyRequest message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.HttpProxyRequest
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.HttpProxyRequest} HttpProxyRequest
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        HttpProxyRequest.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.HttpProxyRequest();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.method = reader.string();
                        break;
                    }
                case 2: {
                        message.path = reader.string();
                        break;
                    }
                case 3: {
                        if (!(message.headers && message.headers.length))
                            message.headers = [];
                        message.headers.push($root.hbb.HeaderEntry.decode(reader, reader.uint32(), undefined, long + 1));
                        break;
                    }
                case 4: {
                        message.body = reader.bytes();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a HttpProxyRequest message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.HttpProxyRequest
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.HttpProxyRequest} HttpProxyRequest
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        HttpProxyRequest.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a HttpProxyRequest message.
         * @function verify
         * @memberof hbb.HttpProxyRequest
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        HttpProxyRequest.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.method != null && message.hasOwnProperty("method"))
                if (!$util.isString(message.method))
                    return "method: string expected";
            if (message.path != null && message.hasOwnProperty("path"))
                if (!$util.isString(message.path))
                    return "path: string expected";
            if (message.headers != null && message.hasOwnProperty("headers")) {
                if (!Array.isArray(message.headers))
                    return "headers: array expected";
                for (let i = 0; i < message.headers.length; ++i) {
                    let error = $root.hbb.HeaderEntry.verify(message.headers[i], long + 1);
                    if (error)
                        return "headers." + error;
                }
            }
            if (message.body != null && message.hasOwnProperty("body"))
                if (!(message.body && typeof message.body.length === "number" || $util.isString(message.body)))
                    return "body: buffer expected";
            return null;
        };

        /**
         * Creates a HttpProxyRequest message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.HttpProxyRequest
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.HttpProxyRequest} HttpProxyRequest
         */
        HttpProxyRequest.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.HttpProxyRequest)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.HttpProxyRequest();
            if (object.method != null)
                message.method = String(object.method);
            if (object.path != null)
                message.path = String(object.path);
            if (object.headers) {
                if (!Array.isArray(object.headers))
                    throw TypeError(".hbb.HttpProxyRequest.headers: array expected");
                message.headers = [];
                for (let i = 0; i < object.headers.length; ++i) {
                    if (typeof object.headers[i] !== "object")
                        throw TypeError(".hbb.HttpProxyRequest.headers: object expected");
                    message.headers[i] = $root.hbb.HeaderEntry.fromObject(object.headers[i], long + 1);
                }
            }
            if (object.body != null)
                if (typeof object.body === "string")
                    $util.base64.decode(object.body, message.body = $util.newBuffer($util.base64.length(object.body)), 0);
                else if (object.body.length >= 0)
                    message.body = object.body;
            return message;
        };

        /**
         * Creates a plain object from a HttpProxyRequest message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.HttpProxyRequest
         * @static
         * @param {hbb.HttpProxyRequest} message HttpProxyRequest
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        HttpProxyRequest.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.arrays || options.defaults)
                object.headers = [];
            if (options.defaults) {
                object.method = "";
                object.path = "";
                if (options.bytes === String)
                    object.body = "";
                else {
                    object.body = [];
                    if (options.bytes !== Array)
                        object.body = $util.newBuffer(object.body);
                }
            }
            if (message.method != null && message.hasOwnProperty("method"))
                object.method = message.method;
            if (message.path != null && message.hasOwnProperty("path"))
                object.path = message.path;
            if (message.headers && message.headers.length) {
                object.headers = [];
                for (let j = 0; j < message.headers.length; ++j)
                    object.headers[j] = $root.hbb.HeaderEntry.toObject(message.headers[j], options);
            }
            if (message.body != null && message.hasOwnProperty("body"))
                object.body = options.bytes === String ? $util.base64.encode(message.body, 0, message.body.length) : options.bytes === Array ? Array.prototype.slice.call(message.body) : message.body;
            return object;
        };

        /**
         * Converts this HttpProxyRequest to JSON.
         * @function toJSON
         * @memberof hbb.HttpProxyRequest
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        HttpProxyRequest.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for HttpProxyRequest
         * @function getTypeUrl
         * @memberof hbb.HttpProxyRequest
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        HttpProxyRequest.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.HttpProxyRequest";
        };

        return HttpProxyRequest;
    })();

    hbb.HttpProxyResponse = (function() {

        /**
         * Properties of a HttpProxyResponse.
         * @memberof hbb
         * @interface IHttpProxyResponse
         * @property {number|null} [status] HttpProxyResponse status
         * @property {Array.<hbb.IHeaderEntry>|null} [headers] HttpProxyResponse headers
         * @property {Uint8Array|null} [body] HttpProxyResponse body
         * @property {string|null} [error] HttpProxyResponse error
         */

        /**
         * Constructs a new HttpProxyResponse.
         * @memberof hbb
         * @classdesc Represents a HttpProxyResponse.
         * @implements IHttpProxyResponse
         * @constructor
         * @param {hbb.IHttpProxyResponse=} [properties] Properties to set
         */
        function HttpProxyResponse(properties) {
            this.headers = [];
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * HttpProxyResponse status.
         * @member {number} status
         * @memberof hbb.HttpProxyResponse
         * @instance
         */
        HttpProxyResponse.prototype.status = 0;

        /**
         * HttpProxyResponse headers.
         * @member {Array.<hbb.IHeaderEntry>} headers
         * @memberof hbb.HttpProxyResponse
         * @instance
         */
        HttpProxyResponse.prototype.headers = $util.emptyArray;

        /**
         * HttpProxyResponse body.
         * @member {Uint8Array} body
         * @memberof hbb.HttpProxyResponse
         * @instance
         */
        HttpProxyResponse.prototype.body = $util.newBuffer([]);

        /**
         * HttpProxyResponse error.
         * @member {string} error
         * @memberof hbb.HttpProxyResponse
         * @instance
         */
        HttpProxyResponse.prototype.error = "";

        /**
         * Creates a new HttpProxyResponse instance using the specified properties.
         * @function create
         * @memberof hbb.HttpProxyResponse
         * @static
         * @param {hbb.IHttpProxyResponse=} [properties] Properties to set
         * @returns {hbb.HttpProxyResponse} HttpProxyResponse instance
         */
        HttpProxyResponse.create = function create(properties) {
            return new HttpProxyResponse(properties);
        };

        /**
         * Encodes the specified HttpProxyResponse message. Does not implicitly {@link hbb.HttpProxyResponse.verify|verify} messages.
         * @function encode
         * @memberof hbb.HttpProxyResponse
         * @static
         * @param {hbb.IHttpProxyResponse} message HttpProxyResponse message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        HttpProxyResponse.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.status != null && Object.hasOwnProperty.call(message, "status"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.status);
            if (message.headers != null && message.headers.length)
                for (let i = 0; i < message.headers.length; ++i)
                    $root.hbb.HeaderEntry.encode(message.headers[i], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            if (message.body != null && Object.hasOwnProperty.call(message, "body"))
                writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.body);
            if (message.error != null && Object.hasOwnProperty.call(message, "error"))
                writer.uint32(/* id 4, wireType 2 =*/34).string(message.error);
            return writer;
        };

        /**
         * Encodes the specified HttpProxyResponse message, length delimited. Does not implicitly {@link hbb.HttpProxyResponse.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.HttpProxyResponse
         * @static
         * @param {hbb.IHttpProxyResponse} message HttpProxyResponse message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        HttpProxyResponse.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a HttpProxyResponse message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.HttpProxyResponse
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.HttpProxyResponse} HttpProxyResponse
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        HttpProxyResponse.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.HttpProxyResponse();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.status = reader.int32();
                        break;
                    }
                case 2: {
                        if (!(message.headers && message.headers.length))
                            message.headers = [];
                        message.headers.push($root.hbb.HeaderEntry.decode(reader, reader.uint32(), undefined, long + 1));
                        break;
                    }
                case 3: {
                        message.body = reader.bytes();
                        break;
                    }
                case 4: {
                        message.error = reader.string();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a HttpProxyResponse message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.HttpProxyResponse
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.HttpProxyResponse} HttpProxyResponse
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        HttpProxyResponse.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a HttpProxyResponse message.
         * @function verify
         * @memberof hbb.HttpProxyResponse
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        HttpProxyResponse.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.status != null && message.hasOwnProperty("status"))
                if (!$util.isInteger(message.status))
                    return "status: integer expected";
            if (message.headers != null && message.hasOwnProperty("headers")) {
                if (!Array.isArray(message.headers))
                    return "headers: array expected";
                for (let i = 0; i < message.headers.length; ++i) {
                    let error = $root.hbb.HeaderEntry.verify(message.headers[i], long + 1);
                    if (error)
                        return "headers." + error;
                }
            }
            if (message.body != null && message.hasOwnProperty("body"))
                if (!(message.body && typeof message.body.length === "number" || $util.isString(message.body)))
                    return "body: buffer expected";
            if (message.error != null && message.hasOwnProperty("error"))
                if (!$util.isString(message.error))
                    return "error: string expected";
            return null;
        };

        /**
         * Creates a HttpProxyResponse message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.HttpProxyResponse
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.HttpProxyResponse} HttpProxyResponse
         */
        HttpProxyResponse.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.HttpProxyResponse)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.HttpProxyResponse();
            if (object.status != null)
                message.status = object.status | 0;
            if (object.headers) {
                if (!Array.isArray(object.headers))
                    throw TypeError(".hbb.HttpProxyResponse.headers: array expected");
                message.headers = [];
                for (let i = 0; i < object.headers.length; ++i) {
                    if (typeof object.headers[i] !== "object")
                        throw TypeError(".hbb.HttpProxyResponse.headers: object expected");
                    message.headers[i] = $root.hbb.HeaderEntry.fromObject(object.headers[i], long + 1);
                }
            }
            if (object.body != null)
                if (typeof object.body === "string")
                    $util.base64.decode(object.body, message.body = $util.newBuffer($util.base64.length(object.body)), 0);
                else if (object.body.length >= 0)
                    message.body = object.body;
            if (object.error != null)
                message.error = String(object.error);
            return message;
        };

        /**
         * Creates a plain object from a HttpProxyResponse message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.HttpProxyResponse
         * @static
         * @param {hbb.HttpProxyResponse} message HttpProxyResponse
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        HttpProxyResponse.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.arrays || options.defaults)
                object.headers = [];
            if (options.defaults) {
                object.status = 0;
                if (options.bytes === String)
                    object.body = "";
                else {
                    object.body = [];
                    if (options.bytes !== Array)
                        object.body = $util.newBuffer(object.body);
                }
                object.error = "";
            }
            if (message.status != null && message.hasOwnProperty("status"))
                object.status = message.status;
            if (message.headers && message.headers.length) {
                object.headers = [];
                for (let j = 0; j < message.headers.length; ++j)
                    object.headers[j] = $root.hbb.HeaderEntry.toObject(message.headers[j], options);
            }
            if (message.body != null && message.hasOwnProperty("body"))
                object.body = options.bytes === String ? $util.base64.encode(message.body, 0, message.body.length) : options.bytes === Array ? Array.prototype.slice.call(message.body) : message.body;
            if (message.error != null && message.hasOwnProperty("error"))
                object.error = message.error;
            return object;
        };

        /**
         * Converts this HttpProxyResponse to JSON.
         * @function toJSON
         * @memberof hbb.HttpProxyResponse
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        HttpProxyResponse.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for HttpProxyResponse
         * @function getTypeUrl
         * @memberof hbb.HttpProxyResponse
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        HttpProxyResponse.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.HttpProxyResponse";
        };

        return HttpProxyResponse;
    })();

    hbb.RendezvousMessage = (function() {

        /**
         * Properties of a RendezvousMessage.
         * @memberof hbb
         * @interface IRendezvousMessage
         * @property {hbb.IRegisterPeer|null} [register_peer] RendezvousMessage register_peer
         * @property {hbb.IRegisterPeerResponse|null} [register_peer_response] RendezvousMessage register_peer_response
         * @property {hbb.IPunchHoleRequest|null} [punch_hole_request] RendezvousMessage punch_hole_request
         * @property {hbb.IPunchHole|null} [punch_hole] RendezvousMessage punch_hole
         * @property {hbb.IPunchHoleSent|null} [punch_hole_sent] RendezvousMessage punch_hole_sent
         * @property {hbb.IPunchHoleResponse|null} [punch_hole_response] RendezvousMessage punch_hole_response
         * @property {hbb.IFetchLocalAddr|null} [fetch_local_addr] RendezvousMessage fetch_local_addr
         * @property {hbb.ILocalAddr|null} [local_addr] RendezvousMessage local_addr
         * @property {hbb.IConfigUpdate|null} [configure_update] RendezvousMessage configure_update
         * @property {hbb.IRegisterPk|null} [register_pk] RendezvousMessage register_pk
         * @property {hbb.IRegisterPkResponse|null} [register_pk_response] RendezvousMessage register_pk_response
         * @property {hbb.ISoftwareUpdate|null} [software_update] RendezvousMessage software_update
         * @property {hbb.IRequestRelay|null} [request_relay] RendezvousMessage request_relay
         * @property {hbb.IRelayResponse|null} [relay_response] RendezvousMessage relay_response
         * @property {hbb.ITestNatRequest|null} [test_nat_request] RendezvousMessage test_nat_request
         * @property {hbb.ITestNatResponse|null} [test_nat_response] RendezvousMessage test_nat_response
         * @property {hbb.IPeerDiscovery|null} [peer_discovery] RendezvousMessage peer_discovery
         * @property {hbb.IOnlineRequest|null} [online_request] RendezvousMessage online_request
         * @property {hbb.IOnlineResponse|null} [online_response] RendezvousMessage online_response
         * @property {hbb.IKeyExchange|null} [key_exchange] RendezvousMessage key_exchange
         * @property {hbb.IHealthCheck|null} [hc] RendezvousMessage hc
         * @property {hbb.IHttpProxyRequest|null} [http_proxy_request] RendezvousMessage http_proxy_request
         * @property {hbb.IHttpProxyResponse|null} [http_proxy_response] RendezvousMessage http_proxy_response
         */

        /**
         * Constructs a new RendezvousMessage.
         * @memberof hbb
         * @classdesc Represents a RendezvousMessage.
         * @implements IRendezvousMessage
         * @constructor
         * @param {hbb.IRendezvousMessage=} [properties] Properties to set
         */
        function RendezvousMessage(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * RendezvousMessage register_peer.
         * @member {hbb.IRegisterPeer|null|undefined} register_peer
         * @memberof hbb.RendezvousMessage
         * @instance
         */
        RendezvousMessage.prototype.register_peer = null;

        /**
         * RendezvousMessage register_peer_response.
         * @member {hbb.IRegisterPeerResponse|null|undefined} register_peer_response
         * @memberof hbb.RendezvousMessage
         * @instance
         */
        RendezvousMessage.prototype.register_peer_response = null;

        /**
         * RendezvousMessage punch_hole_request.
         * @member {hbb.IPunchHoleRequest|null|undefined} punch_hole_request
         * @memberof hbb.RendezvousMessage
         * @instance
         */
        RendezvousMessage.prototype.punch_hole_request = null;

        /**
         * RendezvousMessage punch_hole.
         * @member {hbb.IPunchHole|null|undefined} punch_hole
         * @memberof hbb.RendezvousMessage
         * @instance
         */
        RendezvousMessage.prototype.punch_hole = null;

        /**
         * RendezvousMessage punch_hole_sent.
         * @member {hbb.IPunchHoleSent|null|undefined} punch_hole_sent
         * @memberof hbb.RendezvousMessage
         * @instance
         */
        RendezvousMessage.prototype.punch_hole_sent = null;

        /**
         * RendezvousMessage punch_hole_response.
         * @member {hbb.IPunchHoleResponse|null|undefined} punch_hole_response
         * @memberof hbb.RendezvousMessage
         * @instance
         */
        RendezvousMessage.prototype.punch_hole_response = null;

        /**
         * RendezvousMessage fetch_local_addr.
         * @member {hbb.IFetchLocalAddr|null|undefined} fetch_local_addr
         * @memberof hbb.RendezvousMessage
         * @instance
         */
        RendezvousMessage.prototype.fetch_local_addr = null;

        /**
         * RendezvousMessage local_addr.
         * @member {hbb.ILocalAddr|null|undefined} local_addr
         * @memberof hbb.RendezvousMessage
         * @instance
         */
        RendezvousMessage.prototype.local_addr = null;

        /**
         * RendezvousMessage configure_update.
         * @member {hbb.IConfigUpdate|null|undefined} configure_update
         * @memberof hbb.RendezvousMessage
         * @instance
         */
        RendezvousMessage.prototype.configure_update = null;

        /**
         * RendezvousMessage register_pk.
         * @member {hbb.IRegisterPk|null|undefined} register_pk
         * @memberof hbb.RendezvousMessage
         * @instance
         */
        RendezvousMessage.prototype.register_pk = null;

        /**
         * RendezvousMessage register_pk_response.
         * @member {hbb.IRegisterPkResponse|null|undefined} register_pk_response
         * @memberof hbb.RendezvousMessage
         * @instance
         */
        RendezvousMessage.prototype.register_pk_response = null;

        /**
         * RendezvousMessage software_update.
         * @member {hbb.ISoftwareUpdate|null|undefined} software_update
         * @memberof hbb.RendezvousMessage
         * @instance
         */
        RendezvousMessage.prototype.software_update = null;

        /**
         * RendezvousMessage request_relay.
         * @member {hbb.IRequestRelay|null|undefined} request_relay
         * @memberof hbb.RendezvousMessage
         * @instance
         */
        RendezvousMessage.prototype.request_relay = null;

        /**
         * RendezvousMessage relay_response.
         * @member {hbb.IRelayResponse|null|undefined} relay_response
         * @memberof hbb.RendezvousMessage
         * @instance
         */
        RendezvousMessage.prototype.relay_response = null;

        /**
         * RendezvousMessage test_nat_request.
         * @member {hbb.ITestNatRequest|null|undefined} test_nat_request
         * @memberof hbb.RendezvousMessage
         * @instance
         */
        RendezvousMessage.prototype.test_nat_request = null;

        /**
         * RendezvousMessage test_nat_response.
         * @member {hbb.ITestNatResponse|null|undefined} test_nat_response
         * @memberof hbb.RendezvousMessage
         * @instance
         */
        RendezvousMessage.prototype.test_nat_response = null;

        /**
         * RendezvousMessage peer_discovery.
         * @member {hbb.IPeerDiscovery|null|undefined} peer_discovery
         * @memberof hbb.RendezvousMessage
         * @instance
         */
        RendezvousMessage.prototype.peer_discovery = null;

        /**
         * RendezvousMessage online_request.
         * @member {hbb.IOnlineRequest|null|undefined} online_request
         * @memberof hbb.RendezvousMessage
         * @instance
         */
        RendezvousMessage.prototype.online_request = null;

        /**
         * RendezvousMessage online_response.
         * @member {hbb.IOnlineResponse|null|undefined} online_response
         * @memberof hbb.RendezvousMessage
         * @instance
         */
        RendezvousMessage.prototype.online_response = null;

        /**
         * RendezvousMessage key_exchange.
         * @member {hbb.IKeyExchange|null|undefined} key_exchange
         * @memberof hbb.RendezvousMessage
         * @instance
         */
        RendezvousMessage.prototype.key_exchange = null;

        /**
         * RendezvousMessage hc.
         * @member {hbb.IHealthCheck|null|undefined} hc
         * @memberof hbb.RendezvousMessage
         * @instance
         */
        RendezvousMessage.prototype.hc = null;

        /**
         * RendezvousMessage http_proxy_request.
         * @member {hbb.IHttpProxyRequest|null|undefined} http_proxy_request
         * @memberof hbb.RendezvousMessage
         * @instance
         */
        RendezvousMessage.prototype.http_proxy_request = null;

        /**
         * RendezvousMessage http_proxy_response.
         * @member {hbb.IHttpProxyResponse|null|undefined} http_proxy_response
         * @memberof hbb.RendezvousMessage
         * @instance
         */
        RendezvousMessage.prototype.http_proxy_response = null;

        // OneOf field names bound to virtual getters and setters
        let $oneOfFields;

        /**
         * RendezvousMessage union.
         * @member {"register_peer"|"register_peer_response"|"punch_hole_request"|"punch_hole"|"punch_hole_sent"|"punch_hole_response"|"fetch_local_addr"|"local_addr"|"configure_update"|"register_pk"|"register_pk_response"|"software_update"|"request_relay"|"relay_response"|"test_nat_request"|"test_nat_response"|"peer_discovery"|"online_request"|"online_response"|"key_exchange"|"hc"|"http_proxy_request"|"http_proxy_response"|undefined} union
         * @memberof hbb.RendezvousMessage
         * @instance
         */
        Object.defineProperty(RendezvousMessage.prototype, "union", {
            get: $util.oneOfGetter($oneOfFields = ["register_peer", "register_peer_response", "punch_hole_request", "punch_hole", "punch_hole_sent", "punch_hole_response", "fetch_local_addr", "local_addr", "configure_update", "register_pk", "register_pk_response", "software_update", "request_relay", "relay_response", "test_nat_request", "test_nat_response", "peer_discovery", "online_request", "online_response", "key_exchange", "hc", "http_proxy_request", "http_proxy_response"]),
            set: $util.oneOfSetter($oneOfFields)
        });

        /**
         * Creates a new RendezvousMessage instance using the specified properties.
         * @function create
         * @memberof hbb.RendezvousMessage
         * @static
         * @param {hbb.IRendezvousMessage=} [properties] Properties to set
         * @returns {hbb.RendezvousMessage} RendezvousMessage instance
         */
        RendezvousMessage.create = function create(properties) {
            return new RendezvousMessage(properties);
        };

        /**
         * Encodes the specified RendezvousMessage message. Does not implicitly {@link hbb.RendezvousMessage.verify|verify} messages.
         * @function encode
         * @memberof hbb.RendezvousMessage
         * @static
         * @param {hbb.IRendezvousMessage} message RendezvousMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        RendezvousMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.register_peer != null && Object.hasOwnProperty.call(message, "register_peer"))
                $root.hbb.RegisterPeer.encode(message.register_peer, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim();
            if (message.register_peer_response != null && Object.hasOwnProperty.call(message, "register_peer_response"))
                $root.hbb.RegisterPeerResponse.encode(message.register_peer_response, writer.uint32(/* id 7, wireType 2 =*/58).fork()).ldelim();
            if (message.punch_hole_request != null && Object.hasOwnProperty.call(message, "punch_hole_request"))
                $root.hbb.PunchHoleRequest.encode(message.punch_hole_request, writer.uint32(/* id 8, wireType 2 =*/66).fork()).ldelim();
            if (message.punch_hole != null && Object.hasOwnProperty.call(message, "punch_hole"))
                $root.hbb.PunchHole.encode(message.punch_hole, writer.uint32(/* id 9, wireType 2 =*/74).fork()).ldelim();
            if (message.punch_hole_sent != null && Object.hasOwnProperty.call(message, "punch_hole_sent"))
                $root.hbb.PunchHoleSent.encode(message.punch_hole_sent, writer.uint32(/* id 10, wireType 2 =*/82).fork()).ldelim();
            if (message.punch_hole_response != null && Object.hasOwnProperty.call(message, "punch_hole_response"))
                $root.hbb.PunchHoleResponse.encode(message.punch_hole_response, writer.uint32(/* id 11, wireType 2 =*/90).fork()).ldelim();
            if (message.fetch_local_addr != null && Object.hasOwnProperty.call(message, "fetch_local_addr"))
                $root.hbb.FetchLocalAddr.encode(message.fetch_local_addr, writer.uint32(/* id 12, wireType 2 =*/98).fork()).ldelim();
            if (message.local_addr != null && Object.hasOwnProperty.call(message, "local_addr"))
                $root.hbb.LocalAddr.encode(message.local_addr, writer.uint32(/* id 13, wireType 2 =*/106).fork()).ldelim();
            if (message.configure_update != null && Object.hasOwnProperty.call(message, "configure_update"))
                $root.hbb.ConfigUpdate.encode(message.configure_update, writer.uint32(/* id 14, wireType 2 =*/114).fork()).ldelim();
            if (message.register_pk != null && Object.hasOwnProperty.call(message, "register_pk"))
                $root.hbb.RegisterPk.encode(message.register_pk, writer.uint32(/* id 15, wireType 2 =*/122).fork()).ldelim();
            if (message.register_pk_response != null && Object.hasOwnProperty.call(message, "register_pk_response"))
                $root.hbb.RegisterPkResponse.encode(message.register_pk_response, writer.uint32(/* id 16, wireType 2 =*/130).fork()).ldelim();
            if (message.software_update != null && Object.hasOwnProperty.call(message, "software_update"))
                $root.hbb.SoftwareUpdate.encode(message.software_update, writer.uint32(/* id 17, wireType 2 =*/138).fork()).ldelim();
            if (message.request_relay != null && Object.hasOwnProperty.call(message, "request_relay"))
                $root.hbb.RequestRelay.encode(message.request_relay, writer.uint32(/* id 18, wireType 2 =*/146).fork()).ldelim();
            if (message.relay_response != null && Object.hasOwnProperty.call(message, "relay_response"))
                $root.hbb.RelayResponse.encode(message.relay_response, writer.uint32(/* id 19, wireType 2 =*/154).fork()).ldelim();
            if (message.test_nat_request != null && Object.hasOwnProperty.call(message, "test_nat_request"))
                $root.hbb.TestNatRequest.encode(message.test_nat_request, writer.uint32(/* id 20, wireType 2 =*/162).fork()).ldelim();
            if (message.test_nat_response != null && Object.hasOwnProperty.call(message, "test_nat_response"))
                $root.hbb.TestNatResponse.encode(message.test_nat_response, writer.uint32(/* id 21, wireType 2 =*/170).fork()).ldelim();
            if (message.peer_discovery != null && Object.hasOwnProperty.call(message, "peer_discovery"))
                $root.hbb.PeerDiscovery.encode(message.peer_discovery, writer.uint32(/* id 22, wireType 2 =*/178).fork()).ldelim();
            if (message.online_request != null && Object.hasOwnProperty.call(message, "online_request"))
                $root.hbb.OnlineRequest.encode(message.online_request, writer.uint32(/* id 23, wireType 2 =*/186).fork()).ldelim();
            if (message.online_response != null && Object.hasOwnProperty.call(message, "online_response"))
                $root.hbb.OnlineResponse.encode(message.online_response, writer.uint32(/* id 24, wireType 2 =*/194).fork()).ldelim();
            if (message.key_exchange != null && Object.hasOwnProperty.call(message, "key_exchange"))
                $root.hbb.KeyExchange.encode(message.key_exchange, writer.uint32(/* id 25, wireType 2 =*/202).fork()).ldelim();
            if (message.hc != null && Object.hasOwnProperty.call(message, "hc"))
                $root.hbb.HealthCheck.encode(message.hc, writer.uint32(/* id 26, wireType 2 =*/210).fork()).ldelim();
            if (message.http_proxy_request != null && Object.hasOwnProperty.call(message, "http_proxy_request"))
                $root.hbb.HttpProxyRequest.encode(message.http_proxy_request, writer.uint32(/* id 27, wireType 2 =*/218).fork()).ldelim();
            if (message.http_proxy_response != null && Object.hasOwnProperty.call(message, "http_proxy_response"))
                $root.hbb.HttpProxyResponse.encode(message.http_proxy_response, writer.uint32(/* id 28, wireType 2 =*/226).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified RendezvousMessage message, length delimited. Does not implicitly {@link hbb.RendezvousMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.RendezvousMessage
         * @static
         * @param {hbb.IRendezvousMessage} message RendezvousMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        RendezvousMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a RendezvousMessage message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.RendezvousMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.RendezvousMessage} RendezvousMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        RendezvousMessage.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.RendezvousMessage();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 6: {
                        message.register_peer = $root.hbb.RegisterPeer.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 7: {
                        message.register_peer_response = $root.hbb.RegisterPeerResponse.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 8: {
                        message.punch_hole_request = $root.hbb.PunchHoleRequest.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 9: {
                        message.punch_hole = $root.hbb.PunchHole.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 10: {
                        message.punch_hole_sent = $root.hbb.PunchHoleSent.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 11: {
                        message.punch_hole_response = $root.hbb.PunchHoleResponse.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 12: {
                        message.fetch_local_addr = $root.hbb.FetchLocalAddr.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 13: {
                        message.local_addr = $root.hbb.LocalAddr.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 14: {
                        message.configure_update = $root.hbb.ConfigUpdate.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 15: {
                        message.register_pk = $root.hbb.RegisterPk.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 16: {
                        message.register_pk_response = $root.hbb.RegisterPkResponse.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 17: {
                        message.software_update = $root.hbb.SoftwareUpdate.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 18: {
                        message.request_relay = $root.hbb.RequestRelay.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 19: {
                        message.relay_response = $root.hbb.RelayResponse.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 20: {
                        message.test_nat_request = $root.hbb.TestNatRequest.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 21: {
                        message.test_nat_response = $root.hbb.TestNatResponse.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 22: {
                        message.peer_discovery = $root.hbb.PeerDiscovery.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 23: {
                        message.online_request = $root.hbb.OnlineRequest.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 24: {
                        message.online_response = $root.hbb.OnlineResponse.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 25: {
                        message.key_exchange = $root.hbb.KeyExchange.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 26: {
                        message.hc = $root.hbb.HealthCheck.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 27: {
                        message.http_proxy_request = $root.hbb.HttpProxyRequest.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 28: {
                        message.http_proxy_response = $root.hbb.HttpProxyResponse.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a RendezvousMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.RendezvousMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.RendezvousMessage} RendezvousMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        RendezvousMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a RendezvousMessage message.
         * @function verify
         * @memberof hbb.RendezvousMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        RendezvousMessage.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            let properties = {};
            if (message.register_peer != null && message.hasOwnProperty("register_peer")) {
                properties.union = 1;
                {
                    let error = $root.hbb.RegisterPeer.verify(message.register_peer, long + 1);
                    if (error)
                        return "register_peer." + error;
                }
            }
            if (message.register_peer_response != null && message.hasOwnProperty("register_peer_response")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.RegisterPeerResponse.verify(message.register_peer_response, long + 1);
                    if (error)
                        return "register_peer_response." + error;
                }
            }
            if (message.punch_hole_request != null && message.hasOwnProperty("punch_hole_request")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.PunchHoleRequest.verify(message.punch_hole_request, long + 1);
                    if (error)
                        return "punch_hole_request." + error;
                }
            }
            if (message.punch_hole != null && message.hasOwnProperty("punch_hole")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.PunchHole.verify(message.punch_hole, long + 1);
                    if (error)
                        return "punch_hole." + error;
                }
            }
            if (message.punch_hole_sent != null && message.hasOwnProperty("punch_hole_sent")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.PunchHoleSent.verify(message.punch_hole_sent, long + 1);
                    if (error)
                        return "punch_hole_sent." + error;
                }
            }
            if (message.punch_hole_response != null && message.hasOwnProperty("punch_hole_response")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.PunchHoleResponse.verify(message.punch_hole_response, long + 1);
                    if (error)
                        return "punch_hole_response." + error;
                }
            }
            if (message.fetch_local_addr != null && message.hasOwnProperty("fetch_local_addr")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.FetchLocalAddr.verify(message.fetch_local_addr, long + 1);
                    if (error)
                        return "fetch_local_addr." + error;
                }
            }
            if (message.local_addr != null && message.hasOwnProperty("local_addr")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.LocalAddr.verify(message.local_addr, long + 1);
                    if (error)
                        return "local_addr." + error;
                }
            }
            if (message.configure_update != null && message.hasOwnProperty("configure_update")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.ConfigUpdate.verify(message.configure_update, long + 1);
                    if (error)
                        return "configure_update." + error;
                }
            }
            if (message.register_pk != null && message.hasOwnProperty("register_pk")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.RegisterPk.verify(message.register_pk, long + 1);
                    if (error)
                        return "register_pk." + error;
                }
            }
            if (message.register_pk_response != null && message.hasOwnProperty("register_pk_response")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.RegisterPkResponse.verify(message.register_pk_response, long + 1);
                    if (error)
                        return "register_pk_response." + error;
                }
            }
            if (message.software_update != null && message.hasOwnProperty("software_update")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.SoftwareUpdate.verify(message.software_update, long + 1);
                    if (error)
                        return "software_update." + error;
                }
            }
            if (message.request_relay != null && message.hasOwnProperty("request_relay")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.RequestRelay.verify(message.request_relay, long + 1);
                    if (error)
                        return "request_relay." + error;
                }
            }
            if (message.relay_response != null && message.hasOwnProperty("relay_response")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.RelayResponse.verify(message.relay_response, long + 1);
                    if (error)
                        return "relay_response." + error;
                }
            }
            if (message.test_nat_request != null && message.hasOwnProperty("test_nat_request")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.TestNatRequest.verify(message.test_nat_request, long + 1);
                    if (error)
                        return "test_nat_request." + error;
                }
            }
            if (message.test_nat_response != null && message.hasOwnProperty("test_nat_response")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.TestNatResponse.verify(message.test_nat_response, long + 1);
                    if (error)
                        return "test_nat_response." + error;
                }
            }
            if (message.peer_discovery != null && message.hasOwnProperty("peer_discovery")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.PeerDiscovery.verify(message.peer_discovery, long + 1);
                    if (error)
                        return "peer_discovery." + error;
                }
            }
            if (message.online_request != null && message.hasOwnProperty("online_request")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.OnlineRequest.verify(message.online_request, long + 1);
                    if (error)
                        return "online_request." + error;
                }
            }
            if (message.online_response != null && message.hasOwnProperty("online_response")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.OnlineResponse.verify(message.online_response, long + 1);
                    if (error)
                        return "online_response." + error;
                }
            }
            if (message.key_exchange != null && message.hasOwnProperty("key_exchange")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.KeyExchange.verify(message.key_exchange, long + 1);
                    if (error)
                        return "key_exchange." + error;
                }
            }
            if (message.hc != null && message.hasOwnProperty("hc")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.HealthCheck.verify(message.hc, long + 1);
                    if (error)
                        return "hc." + error;
                }
            }
            if (message.http_proxy_request != null && message.hasOwnProperty("http_proxy_request")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.HttpProxyRequest.verify(message.http_proxy_request, long + 1);
                    if (error)
                        return "http_proxy_request." + error;
                }
            }
            if (message.http_proxy_response != null && message.hasOwnProperty("http_proxy_response")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.HttpProxyResponse.verify(message.http_proxy_response, long + 1);
                    if (error)
                        return "http_proxy_response." + error;
                }
            }
            return null;
        };

        /**
         * Creates a RendezvousMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.RendezvousMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.RendezvousMessage} RendezvousMessage
         */
        RendezvousMessage.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.RendezvousMessage)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.RendezvousMessage();
            if (object.register_peer != null) {
                if (typeof object.register_peer !== "object")
                    throw TypeError(".hbb.RendezvousMessage.register_peer: object expected");
                message.register_peer = $root.hbb.RegisterPeer.fromObject(object.register_peer, long + 1);
            }
            if (object.register_peer_response != null) {
                if (typeof object.register_peer_response !== "object")
                    throw TypeError(".hbb.RendezvousMessage.register_peer_response: object expected");
                message.register_peer_response = $root.hbb.RegisterPeerResponse.fromObject(object.register_peer_response, long + 1);
            }
            if (object.punch_hole_request != null) {
                if (typeof object.punch_hole_request !== "object")
                    throw TypeError(".hbb.RendezvousMessage.punch_hole_request: object expected");
                message.punch_hole_request = $root.hbb.PunchHoleRequest.fromObject(object.punch_hole_request, long + 1);
            }
            if (object.punch_hole != null) {
                if (typeof object.punch_hole !== "object")
                    throw TypeError(".hbb.RendezvousMessage.punch_hole: object expected");
                message.punch_hole = $root.hbb.PunchHole.fromObject(object.punch_hole, long + 1);
            }
            if (object.punch_hole_sent != null) {
                if (typeof object.punch_hole_sent !== "object")
                    throw TypeError(".hbb.RendezvousMessage.punch_hole_sent: object expected");
                message.punch_hole_sent = $root.hbb.PunchHoleSent.fromObject(object.punch_hole_sent, long + 1);
            }
            if (object.punch_hole_response != null) {
                if (typeof object.punch_hole_response !== "object")
                    throw TypeError(".hbb.RendezvousMessage.punch_hole_response: object expected");
                message.punch_hole_response = $root.hbb.PunchHoleResponse.fromObject(object.punch_hole_response, long + 1);
            }
            if (object.fetch_local_addr != null) {
                if (typeof object.fetch_local_addr !== "object")
                    throw TypeError(".hbb.RendezvousMessage.fetch_local_addr: object expected");
                message.fetch_local_addr = $root.hbb.FetchLocalAddr.fromObject(object.fetch_local_addr, long + 1);
            }
            if (object.local_addr != null) {
                if (typeof object.local_addr !== "object")
                    throw TypeError(".hbb.RendezvousMessage.local_addr: object expected");
                message.local_addr = $root.hbb.LocalAddr.fromObject(object.local_addr, long + 1);
            }
            if (object.configure_update != null) {
                if (typeof object.configure_update !== "object")
                    throw TypeError(".hbb.RendezvousMessage.configure_update: object expected");
                message.configure_update = $root.hbb.ConfigUpdate.fromObject(object.configure_update, long + 1);
            }
            if (object.register_pk != null) {
                if (typeof object.register_pk !== "object")
                    throw TypeError(".hbb.RendezvousMessage.register_pk: object expected");
                message.register_pk = $root.hbb.RegisterPk.fromObject(object.register_pk, long + 1);
            }
            if (object.register_pk_response != null) {
                if (typeof object.register_pk_response !== "object")
                    throw TypeError(".hbb.RendezvousMessage.register_pk_response: object expected");
                message.register_pk_response = $root.hbb.RegisterPkResponse.fromObject(object.register_pk_response, long + 1);
            }
            if (object.software_update != null) {
                if (typeof object.software_update !== "object")
                    throw TypeError(".hbb.RendezvousMessage.software_update: object expected");
                message.software_update = $root.hbb.SoftwareUpdate.fromObject(object.software_update, long + 1);
            }
            if (object.request_relay != null) {
                if (typeof object.request_relay !== "object")
                    throw TypeError(".hbb.RendezvousMessage.request_relay: object expected");
                message.request_relay = $root.hbb.RequestRelay.fromObject(object.request_relay, long + 1);
            }
            if (object.relay_response != null) {
                if (typeof object.relay_response !== "object")
                    throw TypeError(".hbb.RendezvousMessage.relay_response: object expected");
                message.relay_response = $root.hbb.RelayResponse.fromObject(object.relay_response, long + 1);
            }
            if (object.test_nat_request != null) {
                if (typeof object.test_nat_request !== "object")
                    throw TypeError(".hbb.RendezvousMessage.test_nat_request: object expected");
                message.test_nat_request = $root.hbb.TestNatRequest.fromObject(object.test_nat_request, long + 1);
            }
            if (object.test_nat_response != null) {
                if (typeof object.test_nat_response !== "object")
                    throw TypeError(".hbb.RendezvousMessage.test_nat_response: object expected");
                message.test_nat_response = $root.hbb.TestNatResponse.fromObject(object.test_nat_response, long + 1);
            }
            if (object.peer_discovery != null) {
                if (typeof object.peer_discovery !== "object")
                    throw TypeError(".hbb.RendezvousMessage.peer_discovery: object expected");
                message.peer_discovery = $root.hbb.PeerDiscovery.fromObject(object.peer_discovery, long + 1);
            }
            if (object.online_request != null) {
                if (typeof object.online_request !== "object")
                    throw TypeError(".hbb.RendezvousMessage.online_request: object expected");
                message.online_request = $root.hbb.OnlineRequest.fromObject(object.online_request, long + 1);
            }
            if (object.online_response != null) {
                if (typeof object.online_response !== "object")
                    throw TypeError(".hbb.RendezvousMessage.online_response: object expected");
                message.online_response = $root.hbb.OnlineResponse.fromObject(object.online_response, long + 1);
            }
            if (object.key_exchange != null) {
                if (typeof object.key_exchange !== "object")
                    throw TypeError(".hbb.RendezvousMessage.key_exchange: object expected");
                message.key_exchange = $root.hbb.KeyExchange.fromObject(object.key_exchange, long + 1);
            }
            if (object.hc != null) {
                if (typeof object.hc !== "object")
                    throw TypeError(".hbb.RendezvousMessage.hc: object expected");
                message.hc = $root.hbb.HealthCheck.fromObject(object.hc, long + 1);
            }
            if (object.http_proxy_request != null) {
                if (typeof object.http_proxy_request !== "object")
                    throw TypeError(".hbb.RendezvousMessage.http_proxy_request: object expected");
                message.http_proxy_request = $root.hbb.HttpProxyRequest.fromObject(object.http_proxy_request, long + 1);
            }
            if (object.http_proxy_response != null) {
                if (typeof object.http_proxy_response !== "object")
                    throw TypeError(".hbb.RendezvousMessage.http_proxy_response: object expected");
                message.http_proxy_response = $root.hbb.HttpProxyResponse.fromObject(object.http_proxy_response, long + 1);
            }
            return message;
        };

        /**
         * Creates a plain object from a RendezvousMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.RendezvousMessage
         * @static
         * @param {hbb.RendezvousMessage} message RendezvousMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        RendezvousMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (message.register_peer != null && message.hasOwnProperty("register_peer")) {
                object.register_peer = $root.hbb.RegisterPeer.toObject(message.register_peer, options);
                if (options.oneofs)
                    object.union = "register_peer";
            }
            if (message.register_peer_response != null && message.hasOwnProperty("register_peer_response")) {
                object.register_peer_response = $root.hbb.RegisterPeerResponse.toObject(message.register_peer_response, options);
                if (options.oneofs)
                    object.union = "register_peer_response";
            }
            if (message.punch_hole_request != null && message.hasOwnProperty("punch_hole_request")) {
                object.punch_hole_request = $root.hbb.PunchHoleRequest.toObject(message.punch_hole_request, options);
                if (options.oneofs)
                    object.union = "punch_hole_request";
            }
            if (message.punch_hole != null && message.hasOwnProperty("punch_hole")) {
                object.punch_hole = $root.hbb.PunchHole.toObject(message.punch_hole, options);
                if (options.oneofs)
                    object.union = "punch_hole";
            }
            if (message.punch_hole_sent != null && message.hasOwnProperty("punch_hole_sent")) {
                object.punch_hole_sent = $root.hbb.PunchHoleSent.toObject(message.punch_hole_sent, options);
                if (options.oneofs)
                    object.union = "punch_hole_sent";
            }
            if (message.punch_hole_response != null && message.hasOwnProperty("punch_hole_response")) {
                object.punch_hole_response = $root.hbb.PunchHoleResponse.toObject(message.punch_hole_response, options);
                if (options.oneofs)
                    object.union = "punch_hole_response";
            }
            if (message.fetch_local_addr != null && message.hasOwnProperty("fetch_local_addr")) {
                object.fetch_local_addr = $root.hbb.FetchLocalAddr.toObject(message.fetch_local_addr, options);
                if (options.oneofs)
                    object.union = "fetch_local_addr";
            }
            if (message.local_addr != null && message.hasOwnProperty("local_addr")) {
                object.local_addr = $root.hbb.LocalAddr.toObject(message.local_addr, options);
                if (options.oneofs)
                    object.union = "local_addr";
            }
            if (message.configure_update != null && message.hasOwnProperty("configure_update")) {
                object.configure_update = $root.hbb.ConfigUpdate.toObject(message.configure_update, options);
                if (options.oneofs)
                    object.union = "configure_update";
            }
            if (message.register_pk != null && message.hasOwnProperty("register_pk")) {
                object.register_pk = $root.hbb.RegisterPk.toObject(message.register_pk, options);
                if (options.oneofs)
                    object.union = "register_pk";
            }
            if (message.register_pk_response != null && message.hasOwnProperty("register_pk_response")) {
                object.register_pk_response = $root.hbb.RegisterPkResponse.toObject(message.register_pk_response, options);
                if (options.oneofs)
                    object.union = "register_pk_response";
            }
            if (message.software_update != null && message.hasOwnProperty("software_update")) {
                object.software_update = $root.hbb.SoftwareUpdate.toObject(message.software_update, options);
                if (options.oneofs)
                    object.union = "software_update";
            }
            if (message.request_relay != null && message.hasOwnProperty("request_relay")) {
                object.request_relay = $root.hbb.RequestRelay.toObject(message.request_relay, options);
                if (options.oneofs)
                    object.union = "request_relay";
            }
            if (message.relay_response != null && message.hasOwnProperty("relay_response")) {
                object.relay_response = $root.hbb.RelayResponse.toObject(message.relay_response, options);
                if (options.oneofs)
                    object.union = "relay_response";
            }
            if (message.test_nat_request != null && message.hasOwnProperty("test_nat_request")) {
                object.test_nat_request = $root.hbb.TestNatRequest.toObject(message.test_nat_request, options);
                if (options.oneofs)
                    object.union = "test_nat_request";
            }
            if (message.test_nat_response != null && message.hasOwnProperty("test_nat_response")) {
                object.test_nat_response = $root.hbb.TestNatResponse.toObject(message.test_nat_response, options);
                if (options.oneofs)
                    object.union = "test_nat_response";
            }
            if (message.peer_discovery != null && message.hasOwnProperty("peer_discovery")) {
                object.peer_discovery = $root.hbb.PeerDiscovery.toObject(message.peer_discovery, options);
                if (options.oneofs)
                    object.union = "peer_discovery";
            }
            if (message.online_request != null && message.hasOwnProperty("online_request")) {
                object.online_request = $root.hbb.OnlineRequest.toObject(message.online_request, options);
                if (options.oneofs)
                    object.union = "online_request";
            }
            if (message.online_response != null && message.hasOwnProperty("online_response")) {
                object.online_response = $root.hbb.OnlineResponse.toObject(message.online_response, options);
                if (options.oneofs)
                    object.union = "online_response";
            }
            if (message.key_exchange != null && message.hasOwnProperty("key_exchange")) {
                object.key_exchange = $root.hbb.KeyExchange.toObject(message.key_exchange, options);
                if (options.oneofs)
                    object.union = "key_exchange";
            }
            if (message.hc != null && message.hasOwnProperty("hc")) {
                object.hc = $root.hbb.HealthCheck.toObject(message.hc, options);
                if (options.oneofs)
                    object.union = "hc";
            }
            if (message.http_proxy_request != null && message.hasOwnProperty("http_proxy_request")) {
                object.http_proxy_request = $root.hbb.HttpProxyRequest.toObject(message.http_proxy_request, options);
                if (options.oneofs)
                    object.union = "http_proxy_request";
            }
            if (message.http_proxy_response != null && message.hasOwnProperty("http_proxy_response")) {
                object.http_proxy_response = $root.hbb.HttpProxyResponse.toObject(message.http_proxy_response, options);
                if (options.oneofs)
                    object.union = "http_proxy_response";
            }
            return object;
        };

        /**
         * Converts this RendezvousMessage to JSON.
         * @function toJSON
         * @memberof hbb.RendezvousMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        RendezvousMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for RendezvousMessage
         * @function getTypeUrl
         * @memberof hbb.RendezvousMessage
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        RendezvousMessage.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.RendezvousMessage";
        };

        return RendezvousMessage;
    })();

    hbb.EncodedVideoFrame = (function() {

        /**
         * Properties of an EncodedVideoFrame.
         * @memberof hbb
         * @interface IEncodedVideoFrame
         * @property {Uint8Array|null} [data] EncodedVideoFrame data
         * @property {boolean|null} [key] EncodedVideoFrame key
         * @property {number|Long|null} [pts] EncodedVideoFrame pts
         */

        /**
         * Constructs a new EncodedVideoFrame.
         * @memberof hbb
         * @classdesc Represents an EncodedVideoFrame.
         * @implements IEncodedVideoFrame
         * @constructor
         * @param {hbb.IEncodedVideoFrame=} [properties] Properties to set
         */
        function EncodedVideoFrame(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * EncodedVideoFrame data.
         * @member {Uint8Array} data
         * @memberof hbb.EncodedVideoFrame
         * @instance
         */
        EncodedVideoFrame.prototype.data = $util.newBuffer([]);

        /**
         * EncodedVideoFrame key.
         * @member {boolean} key
         * @memberof hbb.EncodedVideoFrame
         * @instance
         */
        EncodedVideoFrame.prototype.key = false;

        /**
         * EncodedVideoFrame pts.
         * @member {number|Long} pts
         * @memberof hbb.EncodedVideoFrame
         * @instance
         */
        EncodedVideoFrame.prototype.pts = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * Creates a new EncodedVideoFrame instance using the specified properties.
         * @function create
         * @memberof hbb.EncodedVideoFrame
         * @static
         * @param {hbb.IEncodedVideoFrame=} [properties] Properties to set
         * @returns {hbb.EncodedVideoFrame} EncodedVideoFrame instance
         */
        EncodedVideoFrame.create = function create(properties) {
            return new EncodedVideoFrame(properties);
        };

        /**
         * Encodes the specified EncodedVideoFrame message. Does not implicitly {@link hbb.EncodedVideoFrame.verify|verify} messages.
         * @function encode
         * @memberof hbb.EncodedVideoFrame
         * @static
         * @param {hbb.IEncodedVideoFrame} message EncodedVideoFrame message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        EncodedVideoFrame.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.data != null && Object.hasOwnProperty.call(message, "data"))
                writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.data);
            if (message.key != null && Object.hasOwnProperty.call(message, "key"))
                writer.uint32(/* id 2, wireType 0 =*/16).bool(message.key);
            if (message.pts != null && Object.hasOwnProperty.call(message, "pts"))
                writer.uint32(/* id 3, wireType 0 =*/24).int64(message.pts);
            return writer;
        };

        /**
         * Encodes the specified EncodedVideoFrame message, length delimited. Does not implicitly {@link hbb.EncodedVideoFrame.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.EncodedVideoFrame
         * @static
         * @param {hbb.IEncodedVideoFrame} message EncodedVideoFrame message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        EncodedVideoFrame.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an EncodedVideoFrame message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.EncodedVideoFrame
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.EncodedVideoFrame} EncodedVideoFrame
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        EncodedVideoFrame.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.EncodedVideoFrame();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.data = reader.bytes();
                        break;
                    }
                case 2: {
                        message.key = reader.bool();
                        break;
                    }
                case 3: {
                        message.pts = reader.int64();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an EncodedVideoFrame message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.EncodedVideoFrame
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.EncodedVideoFrame} EncodedVideoFrame
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        EncodedVideoFrame.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an EncodedVideoFrame message.
         * @function verify
         * @memberof hbb.EncodedVideoFrame
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        EncodedVideoFrame.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.data != null && message.hasOwnProperty("data"))
                if (!(message.data && typeof message.data.length === "number" || $util.isString(message.data)))
                    return "data: buffer expected";
            if (message.key != null && message.hasOwnProperty("key"))
                if (typeof message.key !== "boolean")
                    return "key: boolean expected";
            if (message.pts != null && message.hasOwnProperty("pts"))
                if (!$util.isInteger(message.pts) && !(message.pts && $util.isInteger(message.pts.low) && $util.isInteger(message.pts.high)))
                    return "pts: integer|Long expected";
            return null;
        };

        /**
         * Creates an EncodedVideoFrame message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.EncodedVideoFrame
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.EncodedVideoFrame} EncodedVideoFrame
         */
        EncodedVideoFrame.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.EncodedVideoFrame)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.EncodedVideoFrame();
            if (object.data != null)
                if (typeof object.data === "string")
                    $util.base64.decode(object.data, message.data = $util.newBuffer($util.base64.length(object.data)), 0);
                else if (object.data.length >= 0)
                    message.data = object.data;
            if (object.key != null)
                message.key = Boolean(object.key);
            if (object.pts != null)
                if ($util.Long)
                    (message.pts = $util.Long.fromValue(object.pts)).unsigned = false;
                else if (typeof object.pts === "string")
                    message.pts = parseInt(object.pts, 10);
                else if (typeof object.pts === "number")
                    message.pts = object.pts;
                else if (typeof object.pts === "object")
                    message.pts = new $util.LongBits(object.pts.low >>> 0, object.pts.high >>> 0).toNumber();
            return message;
        };

        /**
         * Creates a plain object from an EncodedVideoFrame message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.EncodedVideoFrame
         * @static
         * @param {hbb.EncodedVideoFrame} message EncodedVideoFrame
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        EncodedVideoFrame.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                if (options.bytes === String)
                    object.data = "";
                else {
                    object.data = [];
                    if (options.bytes !== Array)
                        object.data = $util.newBuffer(object.data);
                }
                object.key = false;
                if ($util.Long) {
                    let long = new $util.Long(0, 0, false);
                    object.pts = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.pts = options.longs === String ? "0" : 0;
            }
            if (message.data != null && message.hasOwnProperty("data"))
                object.data = options.bytes === String ? $util.base64.encode(message.data, 0, message.data.length) : options.bytes === Array ? Array.prototype.slice.call(message.data) : message.data;
            if (message.key != null && message.hasOwnProperty("key"))
                object.key = message.key;
            if (message.pts != null && message.hasOwnProperty("pts"))
                if (typeof message.pts === "number")
                    object.pts = options.longs === String ? String(message.pts) : message.pts;
                else
                    object.pts = options.longs === String ? $util.Long.prototype.toString.call(message.pts) : options.longs === Number ? new $util.LongBits(message.pts.low >>> 0, message.pts.high >>> 0).toNumber() : message.pts;
            return object;
        };

        /**
         * Converts this EncodedVideoFrame to JSON.
         * @function toJSON
         * @memberof hbb.EncodedVideoFrame
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        EncodedVideoFrame.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for EncodedVideoFrame
         * @function getTypeUrl
         * @memberof hbb.EncodedVideoFrame
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        EncodedVideoFrame.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.EncodedVideoFrame";
        };

        return EncodedVideoFrame;
    })();

    hbb.EncodedVideoFrames = (function() {

        /**
         * Properties of an EncodedVideoFrames.
         * @memberof hbb
         * @interface IEncodedVideoFrames
         * @property {Array.<hbb.IEncodedVideoFrame>|null} [frames] EncodedVideoFrames frames
         */

        /**
         * Constructs a new EncodedVideoFrames.
         * @memberof hbb
         * @classdesc Represents an EncodedVideoFrames.
         * @implements IEncodedVideoFrames
         * @constructor
         * @param {hbb.IEncodedVideoFrames=} [properties] Properties to set
         */
        function EncodedVideoFrames(properties) {
            this.frames = [];
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * EncodedVideoFrames frames.
         * @member {Array.<hbb.IEncodedVideoFrame>} frames
         * @memberof hbb.EncodedVideoFrames
         * @instance
         */
        EncodedVideoFrames.prototype.frames = $util.emptyArray;

        /**
         * Creates a new EncodedVideoFrames instance using the specified properties.
         * @function create
         * @memberof hbb.EncodedVideoFrames
         * @static
         * @param {hbb.IEncodedVideoFrames=} [properties] Properties to set
         * @returns {hbb.EncodedVideoFrames} EncodedVideoFrames instance
         */
        EncodedVideoFrames.create = function create(properties) {
            return new EncodedVideoFrames(properties);
        };

        /**
         * Encodes the specified EncodedVideoFrames message. Does not implicitly {@link hbb.EncodedVideoFrames.verify|verify} messages.
         * @function encode
         * @memberof hbb.EncodedVideoFrames
         * @static
         * @param {hbb.IEncodedVideoFrames} message EncodedVideoFrames message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        EncodedVideoFrames.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.frames != null && message.frames.length)
                for (let i = 0; i < message.frames.length; ++i)
                    $root.hbb.EncodedVideoFrame.encode(message.frames[i], writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified EncodedVideoFrames message, length delimited. Does not implicitly {@link hbb.EncodedVideoFrames.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.EncodedVideoFrames
         * @static
         * @param {hbb.IEncodedVideoFrames} message EncodedVideoFrames message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        EncodedVideoFrames.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an EncodedVideoFrames message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.EncodedVideoFrames
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.EncodedVideoFrames} EncodedVideoFrames
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        EncodedVideoFrames.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.EncodedVideoFrames();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        if (!(message.frames && message.frames.length))
                            message.frames = [];
                        message.frames.push($root.hbb.EncodedVideoFrame.decode(reader, reader.uint32(), undefined, long + 1));
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an EncodedVideoFrames message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.EncodedVideoFrames
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.EncodedVideoFrames} EncodedVideoFrames
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        EncodedVideoFrames.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an EncodedVideoFrames message.
         * @function verify
         * @memberof hbb.EncodedVideoFrames
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        EncodedVideoFrames.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.frames != null && message.hasOwnProperty("frames")) {
                if (!Array.isArray(message.frames))
                    return "frames: array expected";
                for (let i = 0; i < message.frames.length; ++i) {
                    let error = $root.hbb.EncodedVideoFrame.verify(message.frames[i], long + 1);
                    if (error)
                        return "frames." + error;
                }
            }
            return null;
        };

        /**
         * Creates an EncodedVideoFrames message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.EncodedVideoFrames
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.EncodedVideoFrames} EncodedVideoFrames
         */
        EncodedVideoFrames.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.EncodedVideoFrames)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.EncodedVideoFrames();
            if (object.frames) {
                if (!Array.isArray(object.frames))
                    throw TypeError(".hbb.EncodedVideoFrames.frames: array expected");
                message.frames = [];
                for (let i = 0; i < object.frames.length; ++i) {
                    if (typeof object.frames[i] !== "object")
                        throw TypeError(".hbb.EncodedVideoFrames.frames: object expected");
                    message.frames[i] = $root.hbb.EncodedVideoFrame.fromObject(object.frames[i], long + 1);
                }
            }
            return message;
        };

        /**
         * Creates a plain object from an EncodedVideoFrames message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.EncodedVideoFrames
         * @static
         * @param {hbb.EncodedVideoFrames} message EncodedVideoFrames
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        EncodedVideoFrames.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.arrays || options.defaults)
                object.frames = [];
            if (message.frames && message.frames.length) {
                object.frames = [];
                for (let j = 0; j < message.frames.length; ++j)
                    object.frames[j] = $root.hbb.EncodedVideoFrame.toObject(message.frames[j], options);
            }
            return object;
        };

        /**
         * Converts this EncodedVideoFrames to JSON.
         * @function toJSON
         * @memberof hbb.EncodedVideoFrames
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        EncodedVideoFrames.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for EncodedVideoFrames
         * @function getTypeUrl
         * @memberof hbb.EncodedVideoFrames
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        EncodedVideoFrames.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.EncodedVideoFrames";
        };

        return EncodedVideoFrames;
    })();

    hbb.RGB = (function() {

        /**
         * Properties of a RGB.
         * @memberof hbb
         * @interface IRGB
         * @property {boolean|null} [compress] RGB compress
         */

        /**
         * Constructs a new RGB.
         * @memberof hbb
         * @classdesc Represents a RGB.
         * @implements IRGB
         * @constructor
         * @param {hbb.IRGB=} [properties] Properties to set
         */
        function RGB(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * RGB compress.
         * @member {boolean} compress
         * @memberof hbb.RGB
         * @instance
         */
        RGB.prototype.compress = false;

        /**
         * Creates a new RGB instance using the specified properties.
         * @function create
         * @memberof hbb.RGB
         * @static
         * @param {hbb.IRGB=} [properties] Properties to set
         * @returns {hbb.RGB} RGB instance
         */
        RGB.create = function create(properties) {
            return new RGB(properties);
        };

        /**
         * Encodes the specified RGB message. Does not implicitly {@link hbb.RGB.verify|verify} messages.
         * @function encode
         * @memberof hbb.RGB
         * @static
         * @param {hbb.IRGB} message RGB message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        RGB.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.compress != null && Object.hasOwnProperty.call(message, "compress"))
                writer.uint32(/* id 1, wireType 0 =*/8).bool(message.compress);
            return writer;
        };

        /**
         * Encodes the specified RGB message, length delimited. Does not implicitly {@link hbb.RGB.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.RGB
         * @static
         * @param {hbb.IRGB} message RGB message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        RGB.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a RGB message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.RGB
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.RGB} RGB
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        RGB.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.RGB();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.compress = reader.bool();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a RGB message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.RGB
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.RGB} RGB
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        RGB.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a RGB message.
         * @function verify
         * @memberof hbb.RGB
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        RGB.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.compress != null && message.hasOwnProperty("compress"))
                if (typeof message.compress !== "boolean")
                    return "compress: boolean expected";
            return null;
        };

        /**
         * Creates a RGB message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.RGB
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.RGB} RGB
         */
        RGB.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.RGB)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.RGB();
            if (object.compress != null)
                message.compress = Boolean(object.compress);
            return message;
        };

        /**
         * Creates a plain object from a RGB message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.RGB
         * @static
         * @param {hbb.RGB} message RGB
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        RGB.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults)
                object.compress = false;
            if (message.compress != null && message.hasOwnProperty("compress"))
                object.compress = message.compress;
            return object;
        };

        /**
         * Converts this RGB to JSON.
         * @function toJSON
         * @memberof hbb.RGB
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        RGB.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for RGB
         * @function getTypeUrl
         * @memberof hbb.RGB
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        RGB.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.RGB";
        };

        return RGB;
    })();

    hbb.YUV = (function() {

        /**
         * Properties of a YUV.
         * @memberof hbb
         * @interface IYUV
         * @property {boolean|null} [compress] YUV compress
         * @property {number|null} [stride] YUV stride
         */

        /**
         * Constructs a new YUV.
         * @memberof hbb
         * @classdesc Represents a YUV.
         * @implements IYUV
         * @constructor
         * @param {hbb.IYUV=} [properties] Properties to set
         */
        function YUV(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * YUV compress.
         * @member {boolean} compress
         * @memberof hbb.YUV
         * @instance
         */
        YUV.prototype.compress = false;

        /**
         * YUV stride.
         * @member {number} stride
         * @memberof hbb.YUV
         * @instance
         */
        YUV.prototype.stride = 0;

        /**
         * Creates a new YUV instance using the specified properties.
         * @function create
         * @memberof hbb.YUV
         * @static
         * @param {hbb.IYUV=} [properties] Properties to set
         * @returns {hbb.YUV} YUV instance
         */
        YUV.create = function create(properties) {
            return new YUV(properties);
        };

        /**
         * Encodes the specified YUV message. Does not implicitly {@link hbb.YUV.verify|verify} messages.
         * @function encode
         * @memberof hbb.YUV
         * @static
         * @param {hbb.IYUV} message YUV message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        YUV.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.compress != null && Object.hasOwnProperty.call(message, "compress"))
                writer.uint32(/* id 1, wireType 0 =*/8).bool(message.compress);
            if (message.stride != null && Object.hasOwnProperty.call(message, "stride"))
                writer.uint32(/* id 2, wireType 0 =*/16).int32(message.stride);
            return writer;
        };

        /**
         * Encodes the specified YUV message, length delimited. Does not implicitly {@link hbb.YUV.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.YUV
         * @static
         * @param {hbb.IYUV} message YUV message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        YUV.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a YUV message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.YUV
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.YUV} YUV
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        YUV.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.YUV();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.compress = reader.bool();
                        break;
                    }
                case 2: {
                        message.stride = reader.int32();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a YUV message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.YUV
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.YUV} YUV
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        YUV.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a YUV message.
         * @function verify
         * @memberof hbb.YUV
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        YUV.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.compress != null && message.hasOwnProperty("compress"))
                if (typeof message.compress !== "boolean")
                    return "compress: boolean expected";
            if (message.stride != null && message.hasOwnProperty("stride"))
                if (!$util.isInteger(message.stride))
                    return "stride: integer expected";
            return null;
        };

        /**
         * Creates a YUV message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.YUV
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.YUV} YUV
         */
        YUV.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.YUV)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.YUV();
            if (object.compress != null)
                message.compress = Boolean(object.compress);
            if (object.stride != null)
                message.stride = object.stride | 0;
            return message;
        };

        /**
         * Creates a plain object from a YUV message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.YUV
         * @static
         * @param {hbb.YUV} message YUV
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        YUV.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.compress = false;
                object.stride = 0;
            }
            if (message.compress != null && message.hasOwnProperty("compress"))
                object.compress = message.compress;
            if (message.stride != null && message.hasOwnProperty("stride"))
                object.stride = message.stride;
            return object;
        };

        /**
         * Converts this YUV to JSON.
         * @function toJSON
         * @memberof hbb.YUV
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        YUV.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for YUV
         * @function getTypeUrl
         * @memberof hbb.YUV
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        YUV.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.YUV";
        };

        return YUV;
    })();

    /**
     * Chroma enum.
     * @name hbb.Chroma
     * @enum {number}
     * @property {number} I420=0 I420 value
     * @property {number} I444=1 I444 value
     */
    hbb.Chroma = (function() {
        const valuesById = {}, values = Object.create(valuesById);
        values[valuesById[0] = "I420"] = 0;
        values[valuesById[1] = "I444"] = 1;
        return values;
    })();

    hbb.VideoFrame = (function() {

        /**
         * Properties of a VideoFrame.
         * @memberof hbb
         * @interface IVideoFrame
         * @property {hbb.IEncodedVideoFrames|null} [vp9s] VideoFrame vp9s
         * @property {hbb.IRGB|null} [rgb] VideoFrame rgb
         * @property {hbb.IYUV|null} [yuv] VideoFrame yuv
         * @property {hbb.IEncodedVideoFrames|null} [h264s] VideoFrame h264s
         * @property {hbb.IEncodedVideoFrames|null} [h265s] VideoFrame h265s
         * @property {hbb.IEncodedVideoFrames|null} [vp8s] VideoFrame vp8s
         * @property {hbb.IEncodedVideoFrames|null} [av1s] VideoFrame av1s
         * @property {number|null} [display] VideoFrame display
         */

        /**
         * Constructs a new VideoFrame.
         * @memberof hbb
         * @classdesc Represents a VideoFrame.
         * @implements IVideoFrame
         * @constructor
         * @param {hbb.IVideoFrame=} [properties] Properties to set
         */
        function VideoFrame(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * VideoFrame vp9s.
         * @member {hbb.IEncodedVideoFrames|null|undefined} vp9s
         * @memberof hbb.VideoFrame
         * @instance
         */
        VideoFrame.prototype.vp9s = null;

        /**
         * VideoFrame rgb.
         * @member {hbb.IRGB|null|undefined} rgb
         * @memberof hbb.VideoFrame
         * @instance
         */
        VideoFrame.prototype.rgb = null;

        /**
         * VideoFrame yuv.
         * @member {hbb.IYUV|null|undefined} yuv
         * @memberof hbb.VideoFrame
         * @instance
         */
        VideoFrame.prototype.yuv = null;

        /**
         * VideoFrame h264s.
         * @member {hbb.IEncodedVideoFrames|null|undefined} h264s
         * @memberof hbb.VideoFrame
         * @instance
         */
        VideoFrame.prototype.h264s = null;

        /**
         * VideoFrame h265s.
         * @member {hbb.IEncodedVideoFrames|null|undefined} h265s
         * @memberof hbb.VideoFrame
         * @instance
         */
        VideoFrame.prototype.h265s = null;

        /**
         * VideoFrame vp8s.
         * @member {hbb.IEncodedVideoFrames|null|undefined} vp8s
         * @memberof hbb.VideoFrame
         * @instance
         */
        VideoFrame.prototype.vp8s = null;

        /**
         * VideoFrame av1s.
         * @member {hbb.IEncodedVideoFrames|null|undefined} av1s
         * @memberof hbb.VideoFrame
         * @instance
         */
        VideoFrame.prototype.av1s = null;

        /**
         * VideoFrame display.
         * @member {number} display
         * @memberof hbb.VideoFrame
         * @instance
         */
        VideoFrame.prototype.display = 0;

        // OneOf field names bound to virtual getters and setters
        let $oneOfFields;

        /**
         * VideoFrame union.
         * @member {"vp9s"|"rgb"|"yuv"|"h264s"|"h265s"|"vp8s"|"av1s"|undefined} union
         * @memberof hbb.VideoFrame
         * @instance
         */
        Object.defineProperty(VideoFrame.prototype, "union", {
            get: $util.oneOfGetter($oneOfFields = ["vp9s", "rgb", "yuv", "h264s", "h265s", "vp8s", "av1s"]),
            set: $util.oneOfSetter($oneOfFields)
        });

        /**
         * Creates a new VideoFrame instance using the specified properties.
         * @function create
         * @memberof hbb.VideoFrame
         * @static
         * @param {hbb.IVideoFrame=} [properties] Properties to set
         * @returns {hbb.VideoFrame} VideoFrame instance
         */
        VideoFrame.create = function create(properties) {
            return new VideoFrame(properties);
        };

        /**
         * Encodes the specified VideoFrame message. Does not implicitly {@link hbb.VideoFrame.verify|verify} messages.
         * @function encode
         * @memberof hbb.VideoFrame
         * @static
         * @param {hbb.IVideoFrame} message VideoFrame message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        VideoFrame.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.vp9s != null && Object.hasOwnProperty.call(message, "vp9s"))
                $root.hbb.EncodedVideoFrames.encode(message.vp9s, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim();
            if (message.rgb != null && Object.hasOwnProperty.call(message, "rgb"))
                $root.hbb.RGB.encode(message.rgb, writer.uint32(/* id 7, wireType 2 =*/58).fork()).ldelim();
            if (message.yuv != null && Object.hasOwnProperty.call(message, "yuv"))
                $root.hbb.YUV.encode(message.yuv, writer.uint32(/* id 8, wireType 2 =*/66).fork()).ldelim();
            if (message.h264s != null && Object.hasOwnProperty.call(message, "h264s"))
                $root.hbb.EncodedVideoFrames.encode(message.h264s, writer.uint32(/* id 10, wireType 2 =*/82).fork()).ldelim();
            if (message.h265s != null && Object.hasOwnProperty.call(message, "h265s"))
                $root.hbb.EncodedVideoFrames.encode(message.h265s, writer.uint32(/* id 11, wireType 2 =*/90).fork()).ldelim();
            if (message.vp8s != null && Object.hasOwnProperty.call(message, "vp8s"))
                $root.hbb.EncodedVideoFrames.encode(message.vp8s, writer.uint32(/* id 12, wireType 2 =*/98).fork()).ldelim();
            if (message.av1s != null && Object.hasOwnProperty.call(message, "av1s"))
                $root.hbb.EncodedVideoFrames.encode(message.av1s, writer.uint32(/* id 13, wireType 2 =*/106).fork()).ldelim();
            if (message.display != null && Object.hasOwnProperty.call(message, "display"))
                writer.uint32(/* id 14, wireType 0 =*/112).int32(message.display);
            return writer;
        };

        /**
         * Encodes the specified VideoFrame message, length delimited. Does not implicitly {@link hbb.VideoFrame.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.VideoFrame
         * @static
         * @param {hbb.IVideoFrame} message VideoFrame message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        VideoFrame.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a VideoFrame message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.VideoFrame
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.VideoFrame} VideoFrame
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        VideoFrame.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.VideoFrame();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 6: {
                        message.vp9s = $root.hbb.EncodedVideoFrames.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 7: {
                        message.rgb = $root.hbb.RGB.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 8: {
                        message.yuv = $root.hbb.YUV.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 10: {
                        message.h264s = $root.hbb.EncodedVideoFrames.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 11: {
                        message.h265s = $root.hbb.EncodedVideoFrames.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 12: {
                        message.vp8s = $root.hbb.EncodedVideoFrames.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 13: {
                        message.av1s = $root.hbb.EncodedVideoFrames.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 14: {
                        message.display = reader.int32();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a VideoFrame message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.VideoFrame
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.VideoFrame} VideoFrame
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        VideoFrame.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a VideoFrame message.
         * @function verify
         * @memberof hbb.VideoFrame
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        VideoFrame.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            let properties = {};
            if (message.vp9s != null && message.hasOwnProperty("vp9s")) {
                properties.union = 1;
                {
                    let error = $root.hbb.EncodedVideoFrames.verify(message.vp9s, long + 1);
                    if (error)
                        return "vp9s." + error;
                }
            }
            if (message.rgb != null && message.hasOwnProperty("rgb")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.RGB.verify(message.rgb, long + 1);
                    if (error)
                        return "rgb." + error;
                }
            }
            if (message.yuv != null && message.hasOwnProperty("yuv")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.YUV.verify(message.yuv, long + 1);
                    if (error)
                        return "yuv." + error;
                }
            }
            if (message.h264s != null && message.hasOwnProperty("h264s")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.EncodedVideoFrames.verify(message.h264s, long + 1);
                    if (error)
                        return "h264s." + error;
                }
            }
            if (message.h265s != null && message.hasOwnProperty("h265s")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.EncodedVideoFrames.verify(message.h265s, long + 1);
                    if (error)
                        return "h265s." + error;
                }
            }
            if (message.vp8s != null && message.hasOwnProperty("vp8s")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.EncodedVideoFrames.verify(message.vp8s, long + 1);
                    if (error)
                        return "vp8s." + error;
                }
            }
            if (message.av1s != null && message.hasOwnProperty("av1s")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.EncodedVideoFrames.verify(message.av1s, long + 1);
                    if (error)
                        return "av1s." + error;
                }
            }
            if (message.display != null && message.hasOwnProperty("display"))
                if (!$util.isInteger(message.display))
                    return "display: integer expected";
            return null;
        };

        /**
         * Creates a VideoFrame message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.VideoFrame
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.VideoFrame} VideoFrame
         */
        VideoFrame.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.VideoFrame)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.VideoFrame();
            if (object.vp9s != null) {
                if (typeof object.vp9s !== "object")
                    throw TypeError(".hbb.VideoFrame.vp9s: object expected");
                message.vp9s = $root.hbb.EncodedVideoFrames.fromObject(object.vp9s, long + 1);
            }
            if (object.rgb != null) {
                if (typeof object.rgb !== "object")
                    throw TypeError(".hbb.VideoFrame.rgb: object expected");
                message.rgb = $root.hbb.RGB.fromObject(object.rgb, long + 1);
            }
            if (object.yuv != null) {
                if (typeof object.yuv !== "object")
                    throw TypeError(".hbb.VideoFrame.yuv: object expected");
                message.yuv = $root.hbb.YUV.fromObject(object.yuv, long + 1);
            }
            if (object.h264s != null) {
                if (typeof object.h264s !== "object")
                    throw TypeError(".hbb.VideoFrame.h264s: object expected");
                message.h264s = $root.hbb.EncodedVideoFrames.fromObject(object.h264s, long + 1);
            }
            if (object.h265s != null) {
                if (typeof object.h265s !== "object")
                    throw TypeError(".hbb.VideoFrame.h265s: object expected");
                message.h265s = $root.hbb.EncodedVideoFrames.fromObject(object.h265s, long + 1);
            }
            if (object.vp8s != null) {
                if (typeof object.vp8s !== "object")
                    throw TypeError(".hbb.VideoFrame.vp8s: object expected");
                message.vp8s = $root.hbb.EncodedVideoFrames.fromObject(object.vp8s, long + 1);
            }
            if (object.av1s != null) {
                if (typeof object.av1s !== "object")
                    throw TypeError(".hbb.VideoFrame.av1s: object expected");
                message.av1s = $root.hbb.EncodedVideoFrames.fromObject(object.av1s, long + 1);
            }
            if (object.display != null)
                message.display = object.display | 0;
            return message;
        };

        /**
         * Creates a plain object from a VideoFrame message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.VideoFrame
         * @static
         * @param {hbb.VideoFrame} message VideoFrame
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        VideoFrame.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults)
                object.display = 0;
            if (message.vp9s != null && message.hasOwnProperty("vp9s")) {
                object.vp9s = $root.hbb.EncodedVideoFrames.toObject(message.vp9s, options);
                if (options.oneofs)
                    object.union = "vp9s";
            }
            if (message.rgb != null && message.hasOwnProperty("rgb")) {
                object.rgb = $root.hbb.RGB.toObject(message.rgb, options);
                if (options.oneofs)
                    object.union = "rgb";
            }
            if (message.yuv != null && message.hasOwnProperty("yuv")) {
                object.yuv = $root.hbb.YUV.toObject(message.yuv, options);
                if (options.oneofs)
                    object.union = "yuv";
            }
            if (message.h264s != null && message.hasOwnProperty("h264s")) {
                object.h264s = $root.hbb.EncodedVideoFrames.toObject(message.h264s, options);
                if (options.oneofs)
                    object.union = "h264s";
            }
            if (message.h265s != null && message.hasOwnProperty("h265s")) {
                object.h265s = $root.hbb.EncodedVideoFrames.toObject(message.h265s, options);
                if (options.oneofs)
                    object.union = "h265s";
            }
            if (message.vp8s != null && message.hasOwnProperty("vp8s")) {
                object.vp8s = $root.hbb.EncodedVideoFrames.toObject(message.vp8s, options);
                if (options.oneofs)
                    object.union = "vp8s";
            }
            if (message.av1s != null && message.hasOwnProperty("av1s")) {
                object.av1s = $root.hbb.EncodedVideoFrames.toObject(message.av1s, options);
                if (options.oneofs)
                    object.union = "av1s";
            }
            if (message.display != null && message.hasOwnProperty("display"))
                object.display = message.display;
            return object;
        };

        /**
         * Converts this VideoFrame to JSON.
         * @function toJSON
         * @memberof hbb.VideoFrame
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        VideoFrame.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for VideoFrame
         * @function getTypeUrl
         * @memberof hbb.VideoFrame
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        VideoFrame.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.VideoFrame";
        };

        return VideoFrame;
    })();

    hbb.IdPk = (function() {

        /**
         * Properties of an IdPk.
         * @memberof hbb
         * @interface IIdPk
         * @property {string|null} [id] IdPk id
         * @property {Uint8Array|null} [pk] IdPk pk
         */

        /**
         * Constructs a new IdPk.
         * @memberof hbb
         * @classdesc Represents an IdPk.
         * @implements IIdPk
         * @constructor
         * @param {hbb.IIdPk=} [properties] Properties to set
         */
        function IdPk(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * IdPk id.
         * @member {string} id
         * @memberof hbb.IdPk
         * @instance
         */
        IdPk.prototype.id = "";

        /**
         * IdPk pk.
         * @member {Uint8Array} pk
         * @memberof hbb.IdPk
         * @instance
         */
        IdPk.prototype.pk = $util.newBuffer([]);

        /**
         * Creates a new IdPk instance using the specified properties.
         * @function create
         * @memberof hbb.IdPk
         * @static
         * @param {hbb.IIdPk=} [properties] Properties to set
         * @returns {hbb.IdPk} IdPk instance
         */
        IdPk.create = function create(properties) {
            return new IdPk(properties);
        };

        /**
         * Encodes the specified IdPk message. Does not implicitly {@link hbb.IdPk.verify|verify} messages.
         * @function encode
         * @memberof hbb.IdPk
         * @static
         * @param {hbb.IIdPk} message IdPk message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        IdPk.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.id != null && Object.hasOwnProperty.call(message, "id"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.id);
            if (message.pk != null && Object.hasOwnProperty.call(message, "pk"))
                writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.pk);
            return writer;
        };

        /**
         * Encodes the specified IdPk message, length delimited. Does not implicitly {@link hbb.IdPk.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.IdPk
         * @static
         * @param {hbb.IIdPk} message IdPk message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        IdPk.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an IdPk message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.IdPk
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.IdPk} IdPk
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        IdPk.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.IdPk();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.id = reader.string();
                        break;
                    }
                case 2: {
                        message.pk = reader.bytes();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an IdPk message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.IdPk
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.IdPk} IdPk
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        IdPk.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an IdPk message.
         * @function verify
         * @memberof hbb.IdPk
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        IdPk.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.id != null && message.hasOwnProperty("id"))
                if (!$util.isString(message.id))
                    return "id: string expected";
            if (message.pk != null && message.hasOwnProperty("pk"))
                if (!(message.pk && typeof message.pk.length === "number" || $util.isString(message.pk)))
                    return "pk: buffer expected";
            return null;
        };

        /**
         * Creates an IdPk message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.IdPk
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.IdPk} IdPk
         */
        IdPk.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.IdPk)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.IdPk();
            if (object.id != null)
                message.id = String(object.id);
            if (object.pk != null)
                if (typeof object.pk === "string")
                    $util.base64.decode(object.pk, message.pk = $util.newBuffer($util.base64.length(object.pk)), 0);
                else if (object.pk.length >= 0)
                    message.pk = object.pk;
            return message;
        };

        /**
         * Creates a plain object from an IdPk message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.IdPk
         * @static
         * @param {hbb.IdPk} message IdPk
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        IdPk.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.id = "";
                if (options.bytes === String)
                    object.pk = "";
                else {
                    object.pk = [];
                    if (options.bytes !== Array)
                        object.pk = $util.newBuffer(object.pk);
                }
            }
            if (message.id != null && message.hasOwnProperty("id"))
                object.id = message.id;
            if (message.pk != null && message.hasOwnProperty("pk"))
                object.pk = options.bytes === String ? $util.base64.encode(message.pk, 0, message.pk.length) : options.bytes === Array ? Array.prototype.slice.call(message.pk) : message.pk;
            return object;
        };

        /**
         * Converts this IdPk to JSON.
         * @function toJSON
         * @memberof hbb.IdPk
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        IdPk.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for IdPk
         * @function getTypeUrl
         * @memberof hbb.IdPk
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        IdPk.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.IdPk";
        };

        return IdPk;
    })();

    hbb.DisplayInfo = (function() {

        /**
         * Properties of a DisplayInfo.
         * @memberof hbb
         * @interface IDisplayInfo
         * @property {number|null} [x] DisplayInfo x
         * @property {number|null} [y] DisplayInfo y
         * @property {number|null} [width] DisplayInfo width
         * @property {number|null} [height] DisplayInfo height
         * @property {string|null} [name] DisplayInfo name
         * @property {boolean|null} [online] DisplayInfo online
         * @property {boolean|null} [cursor_embedded] DisplayInfo cursor_embedded
         * @property {hbb.IResolution|null} [original_resolution] DisplayInfo original_resolution
         * @property {number|null} [scale] DisplayInfo scale
         */

        /**
         * Constructs a new DisplayInfo.
         * @memberof hbb
         * @classdesc Represents a DisplayInfo.
         * @implements IDisplayInfo
         * @constructor
         * @param {hbb.IDisplayInfo=} [properties] Properties to set
         */
        function DisplayInfo(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * DisplayInfo x.
         * @member {number} x
         * @memberof hbb.DisplayInfo
         * @instance
         */
        DisplayInfo.prototype.x = 0;

        /**
         * DisplayInfo y.
         * @member {number} y
         * @memberof hbb.DisplayInfo
         * @instance
         */
        DisplayInfo.prototype.y = 0;

        /**
         * DisplayInfo width.
         * @member {number} width
         * @memberof hbb.DisplayInfo
         * @instance
         */
        DisplayInfo.prototype.width = 0;

        /**
         * DisplayInfo height.
         * @member {number} height
         * @memberof hbb.DisplayInfo
         * @instance
         */
        DisplayInfo.prototype.height = 0;

        /**
         * DisplayInfo name.
         * @member {string} name
         * @memberof hbb.DisplayInfo
         * @instance
         */
        DisplayInfo.prototype.name = "";

        /**
         * DisplayInfo online.
         * @member {boolean} online
         * @memberof hbb.DisplayInfo
         * @instance
         */
        DisplayInfo.prototype.online = false;

        /**
         * DisplayInfo cursor_embedded.
         * @member {boolean} cursor_embedded
         * @memberof hbb.DisplayInfo
         * @instance
         */
        DisplayInfo.prototype.cursor_embedded = false;

        /**
         * DisplayInfo original_resolution.
         * @member {hbb.IResolution|null|undefined} original_resolution
         * @memberof hbb.DisplayInfo
         * @instance
         */
        DisplayInfo.prototype.original_resolution = null;

        /**
         * DisplayInfo scale.
         * @member {number} scale
         * @memberof hbb.DisplayInfo
         * @instance
         */
        DisplayInfo.prototype.scale = 0;

        /**
         * Creates a new DisplayInfo instance using the specified properties.
         * @function create
         * @memberof hbb.DisplayInfo
         * @static
         * @param {hbb.IDisplayInfo=} [properties] Properties to set
         * @returns {hbb.DisplayInfo} DisplayInfo instance
         */
        DisplayInfo.create = function create(properties) {
            return new DisplayInfo(properties);
        };

        /**
         * Encodes the specified DisplayInfo message. Does not implicitly {@link hbb.DisplayInfo.verify|verify} messages.
         * @function encode
         * @memberof hbb.DisplayInfo
         * @static
         * @param {hbb.IDisplayInfo} message DisplayInfo message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        DisplayInfo.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.x != null && Object.hasOwnProperty.call(message, "x"))
                writer.uint32(/* id 1, wireType 0 =*/8).sint32(message.x);
            if (message.y != null && Object.hasOwnProperty.call(message, "y"))
                writer.uint32(/* id 2, wireType 0 =*/16).sint32(message.y);
            if (message.width != null && Object.hasOwnProperty.call(message, "width"))
                writer.uint32(/* id 3, wireType 0 =*/24).int32(message.width);
            if (message.height != null && Object.hasOwnProperty.call(message, "height"))
                writer.uint32(/* id 4, wireType 0 =*/32).int32(message.height);
            if (message.name != null && Object.hasOwnProperty.call(message, "name"))
                writer.uint32(/* id 5, wireType 2 =*/42).string(message.name);
            if (message.online != null && Object.hasOwnProperty.call(message, "online"))
                writer.uint32(/* id 6, wireType 0 =*/48).bool(message.online);
            if (message.cursor_embedded != null && Object.hasOwnProperty.call(message, "cursor_embedded"))
                writer.uint32(/* id 7, wireType 0 =*/56).bool(message.cursor_embedded);
            if (message.original_resolution != null && Object.hasOwnProperty.call(message, "original_resolution"))
                $root.hbb.Resolution.encode(message.original_resolution, writer.uint32(/* id 8, wireType 2 =*/66).fork()).ldelim();
            if (message.scale != null && Object.hasOwnProperty.call(message, "scale"))
                writer.uint32(/* id 9, wireType 1 =*/73).double(message.scale);
            return writer;
        };

        /**
         * Encodes the specified DisplayInfo message, length delimited. Does not implicitly {@link hbb.DisplayInfo.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.DisplayInfo
         * @static
         * @param {hbb.IDisplayInfo} message DisplayInfo message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        DisplayInfo.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a DisplayInfo message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.DisplayInfo
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.DisplayInfo} DisplayInfo
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        DisplayInfo.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.DisplayInfo();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.x = reader.sint32();
                        break;
                    }
                case 2: {
                        message.y = reader.sint32();
                        break;
                    }
                case 3: {
                        message.width = reader.int32();
                        break;
                    }
                case 4: {
                        message.height = reader.int32();
                        break;
                    }
                case 5: {
                        message.name = reader.string();
                        break;
                    }
                case 6: {
                        message.online = reader.bool();
                        break;
                    }
                case 7: {
                        message.cursor_embedded = reader.bool();
                        break;
                    }
                case 8: {
                        message.original_resolution = $root.hbb.Resolution.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 9: {
                        message.scale = reader.double();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a DisplayInfo message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.DisplayInfo
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.DisplayInfo} DisplayInfo
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        DisplayInfo.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a DisplayInfo message.
         * @function verify
         * @memberof hbb.DisplayInfo
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        DisplayInfo.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.x != null && message.hasOwnProperty("x"))
                if (!$util.isInteger(message.x))
                    return "x: integer expected";
            if (message.y != null && message.hasOwnProperty("y"))
                if (!$util.isInteger(message.y))
                    return "y: integer expected";
            if (message.width != null && message.hasOwnProperty("width"))
                if (!$util.isInteger(message.width))
                    return "width: integer expected";
            if (message.height != null && message.hasOwnProperty("height"))
                if (!$util.isInteger(message.height))
                    return "height: integer expected";
            if (message.name != null && message.hasOwnProperty("name"))
                if (!$util.isString(message.name))
                    return "name: string expected";
            if (message.online != null && message.hasOwnProperty("online"))
                if (typeof message.online !== "boolean")
                    return "online: boolean expected";
            if (message.cursor_embedded != null && message.hasOwnProperty("cursor_embedded"))
                if (typeof message.cursor_embedded !== "boolean")
                    return "cursor_embedded: boolean expected";
            if (message.original_resolution != null && message.hasOwnProperty("original_resolution")) {
                let error = $root.hbb.Resolution.verify(message.original_resolution, long + 1);
                if (error)
                    return "original_resolution." + error;
            }
            if (message.scale != null && message.hasOwnProperty("scale"))
                if (typeof message.scale !== "number")
                    return "scale: number expected";
            return null;
        };

        /**
         * Creates a DisplayInfo message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.DisplayInfo
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.DisplayInfo} DisplayInfo
         */
        DisplayInfo.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.DisplayInfo)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.DisplayInfo();
            if (object.x != null)
                message.x = object.x | 0;
            if (object.y != null)
                message.y = object.y | 0;
            if (object.width != null)
                message.width = object.width | 0;
            if (object.height != null)
                message.height = object.height | 0;
            if (object.name != null)
                message.name = String(object.name);
            if (object.online != null)
                message.online = Boolean(object.online);
            if (object.cursor_embedded != null)
                message.cursor_embedded = Boolean(object.cursor_embedded);
            if (object.original_resolution != null) {
                if (typeof object.original_resolution !== "object")
                    throw TypeError(".hbb.DisplayInfo.original_resolution: object expected");
                message.original_resolution = $root.hbb.Resolution.fromObject(object.original_resolution, long + 1);
            }
            if (object.scale != null)
                message.scale = Number(object.scale);
            return message;
        };

        /**
         * Creates a plain object from a DisplayInfo message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.DisplayInfo
         * @static
         * @param {hbb.DisplayInfo} message DisplayInfo
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        DisplayInfo.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.x = 0;
                object.y = 0;
                object.width = 0;
                object.height = 0;
                object.name = "";
                object.online = false;
                object.cursor_embedded = false;
                object.original_resolution = null;
                object.scale = 0;
            }
            if (message.x != null && message.hasOwnProperty("x"))
                object.x = message.x;
            if (message.y != null && message.hasOwnProperty("y"))
                object.y = message.y;
            if (message.width != null && message.hasOwnProperty("width"))
                object.width = message.width;
            if (message.height != null && message.hasOwnProperty("height"))
                object.height = message.height;
            if (message.name != null && message.hasOwnProperty("name"))
                object.name = message.name;
            if (message.online != null && message.hasOwnProperty("online"))
                object.online = message.online;
            if (message.cursor_embedded != null && message.hasOwnProperty("cursor_embedded"))
                object.cursor_embedded = message.cursor_embedded;
            if (message.original_resolution != null && message.hasOwnProperty("original_resolution"))
                object.original_resolution = $root.hbb.Resolution.toObject(message.original_resolution, options);
            if (message.scale != null && message.hasOwnProperty("scale"))
                object.scale = options.json && !isFinite(message.scale) ? String(message.scale) : message.scale;
            return object;
        };

        /**
         * Converts this DisplayInfo to JSON.
         * @function toJSON
         * @memberof hbb.DisplayInfo
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        DisplayInfo.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for DisplayInfo
         * @function getTypeUrl
         * @memberof hbb.DisplayInfo
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        DisplayInfo.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.DisplayInfo";
        };

        return DisplayInfo;
    })();

    hbb.PortForward = (function() {

        /**
         * Properties of a PortForward.
         * @memberof hbb
         * @interface IPortForward
         * @property {string|null} [host] PortForward host
         * @property {number|null} [port] PortForward port
         */

        /**
         * Constructs a new PortForward.
         * @memberof hbb
         * @classdesc Represents a PortForward.
         * @implements IPortForward
         * @constructor
         * @param {hbb.IPortForward=} [properties] Properties to set
         */
        function PortForward(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * PortForward host.
         * @member {string} host
         * @memberof hbb.PortForward
         * @instance
         */
        PortForward.prototype.host = "";

        /**
         * PortForward port.
         * @member {number} port
         * @memberof hbb.PortForward
         * @instance
         */
        PortForward.prototype.port = 0;

        /**
         * Creates a new PortForward instance using the specified properties.
         * @function create
         * @memberof hbb.PortForward
         * @static
         * @param {hbb.IPortForward=} [properties] Properties to set
         * @returns {hbb.PortForward} PortForward instance
         */
        PortForward.create = function create(properties) {
            return new PortForward(properties);
        };

        /**
         * Encodes the specified PortForward message. Does not implicitly {@link hbb.PortForward.verify|verify} messages.
         * @function encode
         * @memberof hbb.PortForward
         * @static
         * @param {hbb.IPortForward} message PortForward message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        PortForward.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.host != null && Object.hasOwnProperty.call(message, "host"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.host);
            if (message.port != null && Object.hasOwnProperty.call(message, "port"))
                writer.uint32(/* id 2, wireType 0 =*/16).int32(message.port);
            return writer;
        };

        /**
         * Encodes the specified PortForward message, length delimited. Does not implicitly {@link hbb.PortForward.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.PortForward
         * @static
         * @param {hbb.IPortForward} message PortForward message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        PortForward.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a PortForward message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.PortForward
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.PortForward} PortForward
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        PortForward.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.PortForward();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.host = reader.string();
                        break;
                    }
                case 2: {
                        message.port = reader.int32();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a PortForward message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.PortForward
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.PortForward} PortForward
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        PortForward.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a PortForward message.
         * @function verify
         * @memberof hbb.PortForward
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        PortForward.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.host != null && message.hasOwnProperty("host"))
                if (!$util.isString(message.host))
                    return "host: string expected";
            if (message.port != null && message.hasOwnProperty("port"))
                if (!$util.isInteger(message.port))
                    return "port: integer expected";
            return null;
        };

        /**
         * Creates a PortForward message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.PortForward
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.PortForward} PortForward
         */
        PortForward.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.PortForward)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.PortForward();
            if (object.host != null)
                message.host = String(object.host);
            if (object.port != null)
                message.port = object.port | 0;
            return message;
        };

        /**
         * Creates a plain object from a PortForward message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.PortForward
         * @static
         * @param {hbb.PortForward} message PortForward
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        PortForward.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.host = "";
                object.port = 0;
            }
            if (message.host != null && message.hasOwnProperty("host"))
                object.host = message.host;
            if (message.port != null && message.hasOwnProperty("port"))
                object.port = message.port;
            return object;
        };

        /**
         * Converts this PortForward to JSON.
         * @function toJSON
         * @memberof hbb.PortForward
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        PortForward.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for PortForward
         * @function getTypeUrl
         * @memberof hbb.PortForward
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        PortForward.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.PortForward";
        };

        return PortForward;
    })();

    hbb.FileTransfer = (function() {

        /**
         * Properties of a FileTransfer.
         * @memberof hbb
         * @interface IFileTransfer
         * @property {string|null} [dir] FileTransfer dir
         * @property {boolean|null} [show_hidden] FileTransfer show_hidden
         */

        /**
         * Constructs a new FileTransfer.
         * @memberof hbb
         * @classdesc Represents a FileTransfer.
         * @implements IFileTransfer
         * @constructor
         * @param {hbb.IFileTransfer=} [properties] Properties to set
         */
        function FileTransfer(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * FileTransfer dir.
         * @member {string} dir
         * @memberof hbb.FileTransfer
         * @instance
         */
        FileTransfer.prototype.dir = "";

        /**
         * FileTransfer show_hidden.
         * @member {boolean} show_hidden
         * @memberof hbb.FileTransfer
         * @instance
         */
        FileTransfer.prototype.show_hidden = false;

        /**
         * Creates a new FileTransfer instance using the specified properties.
         * @function create
         * @memberof hbb.FileTransfer
         * @static
         * @param {hbb.IFileTransfer=} [properties] Properties to set
         * @returns {hbb.FileTransfer} FileTransfer instance
         */
        FileTransfer.create = function create(properties) {
            return new FileTransfer(properties);
        };

        /**
         * Encodes the specified FileTransfer message. Does not implicitly {@link hbb.FileTransfer.verify|verify} messages.
         * @function encode
         * @memberof hbb.FileTransfer
         * @static
         * @param {hbb.IFileTransfer} message FileTransfer message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FileTransfer.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.dir != null && Object.hasOwnProperty.call(message, "dir"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.dir);
            if (message.show_hidden != null && Object.hasOwnProperty.call(message, "show_hidden"))
                writer.uint32(/* id 2, wireType 0 =*/16).bool(message.show_hidden);
            return writer;
        };

        /**
         * Encodes the specified FileTransfer message, length delimited. Does not implicitly {@link hbb.FileTransfer.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.FileTransfer
         * @static
         * @param {hbb.IFileTransfer} message FileTransfer message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FileTransfer.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a FileTransfer message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.FileTransfer
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.FileTransfer} FileTransfer
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FileTransfer.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.FileTransfer();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.dir = reader.string();
                        break;
                    }
                case 2: {
                        message.show_hidden = reader.bool();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a FileTransfer message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.FileTransfer
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.FileTransfer} FileTransfer
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FileTransfer.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a FileTransfer message.
         * @function verify
         * @memberof hbb.FileTransfer
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        FileTransfer.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.dir != null && message.hasOwnProperty("dir"))
                if (!$util.isString(message.dir))
                    return "dir: string expected";
            if (message.show_hidden != null && message.hasOwnProperty("show_hidden"))
                if (typeof message.show_hidden !== "boolean")
                    return "show_hidden: boolean expected";
            return null;
        };

        /**
         * Creates a FileTransfer message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.FileTransfer
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.FileTransfer} FileTransfer
         */
        FileTransfer.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.FileTransfer)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.FileTransfer();
            if (object.dir != null)
                message.dir = String(object.dir);
            if (object.show_hidden != null)
                message.show_hidden = Boolean(object.show_hidden);
            return message;
        };

        /**
         * Creates a plain object from a FileTransfer message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.FileTransfer
         * @static
         * @param {hbb.FileTransfer} message FileTransfer
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        FileTransfer.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.dir = "";
                object.show_hidden = false;
            }
            if (message.dir != null && message.hasOwnProperty("dir"))
                object.dir = message.dir;
            if (message.show_hidden != null && message.hasOwnProperty("show_hidden"))
                object.show_hidden = message.show_hidden;
            return object;
        };

        /**
         * Converts this FileTransfer to JSON.
         * @function toJSON
         * @memberof hbb.FileTransfer
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        FileTransfer.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for FileTransfer
         * @function getTypeUrl
         * @memberof hbb.FileTransfer
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        FileTransfer.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.FileTransfer";
        };

        return FileTransfer;
    })();

    hbb.ViewCamera = (function() {

        /**
         * Properties of a ViewCamera.
         * @memberof hbb
         * @interface IViewCamera
         */

        /**
         * Constructs a new ViewCamera.
         * @memberof hbb
         * @classdesc Represents a ViewCamera.
         * @implements IViewCamera
         * @constructor
         * @param {hbb.IViewCamera=} [properties] Properties to set
         */
        function ViewCamera(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * Creates a new ViewCamera instance using the specified properties.
         * @function create
         * @memberof hbb.ViewCamera
         * @static
         * @param {hbb.IViewCamera=} [properties] Properties to set
         * @returns {hbb.ViewCamera} ViewCamera instance
         */
        ViewCamera.create = function create(properties) {
            return new ViewCamera(properties);
        };

        /**
         * Encodes the specified ViewCamera message. Does not implicitly {@link hbb.ViewCamera.verify|verify} messages.
         * @function encode
         * @memberof hbb.ViewCamera
         * @static
         * @param {hbb.IViewCamera} message ViewCamera message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ViewCamera.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            return writer;
        };

        /**
         * Encodes the specified ViewCamera message, length delimited. Does not implicitly {@link hbb.ViewCamera.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.ViewCamera
         * @static
         * @param {hbb.IViewCamera} message ViewCamera message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ViewCamera.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a ViewCamera message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.ViewCamera
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.ViewCamera} ViewCamera
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ViewCamera.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.ViewCamera();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a ViewCamera message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.ViewCamera
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.ViewCamera} ViewCamera
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ViewCamera.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a ViewCamera message.
         * @function verify
         * @memberof hbb.ViewCamera
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ViewCamera.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            return null;
        };

        /**
         * Creates a ViewCamera message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.ViewCamera
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.ViewCamera} ViewCamera
         */
        ViewCamera.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.ViewCamera)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            return new $root.hbb.ViewCamera();
        };

        /**
         * Creates a plain object from a ViewCamera message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.ViewCamera
         * @static
         * @param {hbb.ViewCamera} message ViewCamera
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ViewCamera.toObject = function toObject() {
            return {};
        };

        /**
         * Converts this ViewCamera to JSON.
         * @function toJSON
         * @memberof hbb.ViewCamera
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ViewCamera.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for ViewCamera
         * @function getTypeUrl
         * @memberof hbb.ViewCamera
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        ViewCamera.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.ViewCamera";
        };

        return ViewCamera;
    })();

    hbb.OSLogin = (function() {

        /**
         * Properties of a OSLogin.
         * @memberof hbb
         * @interface IOSLogin
         * @property {string|null} [username] OSLogin username
         * @property {string|null} [password] OSLogin password
         */

        /**
         * Constructs a new OSLogin.
         * @memberof hbb
         * @classdesc Represents a OSLogin.
         * @implements IOSLogin
         * @constructor
         * @param {hbb.IOSLogin=} [properties] Properties to set
         */
        function OSLogin(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * OSLogin username.
         * @member {string} username
         * @memberof hbb.OSLogin
         * @instance
         */
        OSLogin.prototype.username = "";

        /**
         * OSLogin password.
         * @member {string} password
         * @memberof hbb.OSLogin
         * @instance
         */
        OSLogin.prototype.password = "";

        /**
         * Creates a new OSLogin instance using the specified properties.
         * @function create
         * @memberof hbb.OSLogin
         * @static
         * @param {hbb.IOSLogin=} [properties] Properties to set
         * @returns {hbb.OSLogin} OSLogin instance
         */
        OSLogin.create = function create(properties) {
            return new OSLogin(properties);
        };

        /**
         * Encodes the specified OSLogin message. Does not implicitly {@link hbb.OSLogin.verify|verify} messages.
         * @function encode
         * @memberof hbb.OSLogin
         * @static
         * @param {hbb.IOSLogin} message OSLogin message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        OSLogin.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.username != null && Object.hasOwnProperty.call(message, "username"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.username);
            if (message.password != null && Object.hasOwnProperty.call(message, "password"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.password);
            return writer;
        };

        /**
         * Encodes the specified OSLogin message, length delimited. Does not implicitly {@link hbb.OSLogin.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.OSLogin
         * @static
         * @param {hbb.IOSLogin} message OSLogin message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        OSLogin.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a OSLogin message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.OSLogin
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.OSLogin} OSLogin
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        OSLogin.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.OSLogin();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.username = reader.string();
                        break;
                    }
                case 2: {
                        message.password = reader.string();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a OSLogin message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.OSLogin
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.OSLogin} OSLogin
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        OSLogin.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a OSLogin message.
         * @function verify
         * @memberof hbb.OSLogin
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        OSLogin.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.username != null && message.hasOwnProperty("username"))
                if (!$util.isString(message.username))
                    return "username: string expected";
            if (message.password != null && message.hasOwnProperty("password"))
                if (!$util.isString(message.password))
                    return "password: string expected";
            return null;
        };

        /**
         * Creates a OSLogin message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.OSLogin
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.OSLogin} OSLogin
         */
        OSLogin.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.OSLogin)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.OSLogin();
            if (object.username != null)
                message.username = String(object.username);
            if (object.password != null)
                message.password = String(object.password);
            return message;
        };

        /**
         * Creates a plain object from a OSLogin message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.OSLogin
         * @static
         * @param {hbb.OSLogin} message OSLogin
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        OSLogin.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.username = "";
                object.password = "";
            }
            if (message.username != null && message.hasOwnProperty("username"))
                object.username = message.username;
            if (message.password != null && message.hasOwnProperty("password"))
                object.password = message.password;
            return object;
        };

        /**
         * Converts this OSLogin to JSON.
         * @function toJSON
         * @memberof hbb.OSLogin
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        OSLogin.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for OSLogin
         * @function getTypeUrl
         * @memberof hbb.OSLogin
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        OSLogin.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.OSLogin";
        };

        return OSLogin;
    })();

    hbb.LoginRequest = (function() {

        /**
         * Properties of a LoginRequest.
         * @memberof hbb
         * @interface ILoginRequest
         * @property {string|null} [username] LoginRequest username
         * @property {Uint8Array|null} [password] LoginRequest password
         * @property {string|null} [my_id] LoginRequest my_id
         * @property {string|null} [my_name] LoginRequest my_name
         * @property {hbb.IOptionMessage|null} [option] LoginRequest option
         * @property {hbb.IFileTransfer|null} [file_transfer] LoginRequest file_transfer
         * @property {hbb.IPortForward|null} [port_forward] LoginRequest port_forward
         * @property {hbb.IViewCamera|null} [view_camera] LoginRequest view_camera
         * @property {boolean|null} [video_ack_required] LoginRequest video_ack_required
         * @property {number|Long|null} [session_id] LoginRequest session_id
         * @property {string|null} [version] LoginRequest version
         * @property {hbb.IOSLogin|null} [os_login] LoginRequest os_login
         * @property {string|null} [my_platform] LoginRequest my_platform
         * @property {Uint8Array|null} [hwid] LoginRequest hwid
         */

        /**
         * Constructs a new LoginRequest.
         * @memberof hbb
         * @classdesc Represents a LoginRequest.
         * @implements ILoginRequest
         * @constructor
         * @param {hbb.ILoginRequest=} [properties] Properties to set
         */
        function LoginRequest(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * LoginRequest username.
         * @member {string} username
         * @memberof hbb.LoginRequest
         * @instance
         */
        LoginRequest.prototype.username = "";

        /**
         * LoginRequest password.
         * @member {Uint8Array} password
         * @memberof hbb.LoginRequest
         * @instance
         */
        LoginRequest.prototype.password = $util.newBuffer([]);

        /**
         * LoginRequest my_id.
         * @member {string} my_id
         * @memberof hbb.LoginRequest
         * @instance
         */
        LoginRequest.prototype.my_id = "";

        /**
         * LoginRequest my_name.
         * @member {string} my_name
         * @memberof hbb.LoginRequest
         * @instance
         */
        LoginRequest.prototype.my_name = "";

        /**
         * LoginRequest option.
         * @member {hbb.IOptionMessage|null|undefined} option
         * @memberof hbb.LoginRequest
         * @instance
         */
        LoginRequest.prototype.option = null;

        /**
         * LoginRequest file_transfer.
         * @member {hbb.IFileTransfer|null|undefined} file_transfer
         * @memberof hbb.LoginRequest
         * @instance
         */
        LoginRequest.prototype.file_transfer = null;

        /**
         * LoginRequest port_forward.
         * @member {hbb.IPortForward|null|undefined} port_forward
         * @memberof hbb.LoginRequest
         * @instance
         */
        LoginRequest.prototype.port_forward = null;

        /**
         * LoginRequest view_camera.
         * @member {hbb.IViewCamera|null|undefined} view_camera
         * @memberof hbb.LoginRequest
         * @instance
         */
        LoginRequest.prototype.view_camera = null;

        /**
         * LoginRequest video_ack_required.
         * @member {boolean} video_ack_required
         * @memberof hbb.LoginRequest
         * @instance
         */
        LoginRequest.prototype.video_ack_required = false;

        /**
         * LoginRequest session_id.
         * @member {number|Long} session_id
         * @memberof hbb.LoginRequest
         * @instance
         */
        LoginRequest.prototype.session_id = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * LoginRequest version.
         * @member {string} version
         * @memberof hbb.LoginRequest
         * @instance
         */
        LoginRequest.prototype.version = "";

        /**
         * LoginRequest os_login.
         * @member {hbb.IOSLogin|null|undefined} os_login
         * @memberof hbb.LoginRequest
         * @instance
         */
        LoginRequest.prototype.os_login = null;

        /**
         * LoginRequest my_platform.
         * @member {string} my_platform
         * @memberof hbb.LoginRequest
         * @instance
         */
        LoginRequest.prototype.my_platform = "";

        /**
         * LoginRequest hwid.
         * @member {Uint8Array} hwid
         * @memberof hbb.LoginRequest
         * @instance
         */
        LoginRequest.prototype.hwid = $util.newBuffer([]);

        // OneOf field names bound to virtual getters and setters
        let $oneOfFields;

        /**
         * LoginRequest union.
         * @member {"file_transfer"|"port_forward"|"view_camera"|undefined} union
         * @memberof hbb.LoginRequest
         * @instance
         */
        Object.defineProperty(LoginRequest.prototype, "union", {
            get: $util.oneOfGetter($oneOfFields = ["file_transfer", "port_forward", "view_camera"]),
            set: $util.oneOfSetter($oneOfFields)
        });

        /**
         * Creates a new LoginRequest instance using the specified properties.
         * @function create
         * @memberof hbb.LoginRequest
         * @static
         * @param {hbb.ILoginRequest=} [properties] Properties to set
         * @returns {hbb.LoginRequest} LoginRequest instance
         */
        LoginRequest.create = function create(properties) {
            return new LoginRequest(properties);
        };

        /**
         * Encodes the specified LoginRequest message. Does not implicitly {@link hbb.LoginRequest.verify|verify} messages.
         * @function encode
         * @memberof hbb.LoginRequest
         * @static
         * @param {hbb.ILoginRequest} message LoginRequest message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        LoginRequest.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.username != null && Object.hasOwnProperty.call(message, "username"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.username);
            if (message.password != null && Object.hasOwnProperty.call(message, "password"))
                writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.password);
            if (message.my_id != null && Object.hasOwnProperty.call(message, "my_id"))
                writer.uint32(/* id 4, wireType 2 =*/34).string(message.my_id);
            if (message.my_name != null && Object.hasOwnProperty.call(message, "my_name"))
                writer.uint32(/* id 5, wireType 2 =*/42).string(message.my_name);
            if (message.option != null && Object.hasOwnProperty.call(message, "option"))
                $root.hbb.OptionMessage.encode(message.option, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim();
            if (message.file_transfer != null && Object.hasOwnProperty.call(message, "file_transfer"))
                $root.hbb.FileTransfer.encode(message.file_transfer, writer.uint32(/* id 7, wireType 2 =*/58).fork()).ldelim();
            if (message.port_forward != null && Object.hasOwnProperty.call(message, "port_forward"))
                $root.hbb.PortForward.encode(message.port_forward, writer.uint32(/* id 8, wireType 2 =*/66).fork()).ldelim();
            if (message.video_ack_required != null && Object.hasOwnProperty.call(message, "video_ack_required"))
                writer.uint32(/* id 9, wireType 0 =*/72).bool(message.video_ack_required);
            if (message.session_id != null && Object.hasOwnProperty.call(message, "session_id"))
                writer.uint32(/* id 10, wireType 0 =*/80).uint64(message.session_id);
            if (message.version != null && Object.hasOwnProperty.call(message, "version"))
                writer.uint32(/* id 11, wireType 2 =*/90).string(message.version);
            if (message.os_login != null && Object.hasOwnProperty.call(message, "os_login"))
                $root.hbb.OSLogin.encode(message.os_login, writer.uint32(/* id 12, wireType 2 =*/98).fork()).ldelim();
            if (message.my_platform != null && Object.hasOwnProperty.call(message, "my_platform"))
                writer.uint32(/* id 13, wireType 2 =*/106).string(message.my_platform);
            if (message.hwid != null && Object.hasOwnProperty.call(message, "hwid"))
                writer.uint32(/* id 14, wireType 2 =*/114).bytes(message.hwid);
            if (message.view_camera != null && Object.hasOwnProperty.call(message, "view_camera"))
                $root.hbb.ViewCamera.encode(message.view_camera, writer.uint32(/* id 15, wireType 2 =*/122).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified LoginRequest message, length delimited. Does not implicitly {@link hbb.LoginRequest.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.LoginRequest
         * @static
         * @param {hbb.ILoginRequest} message LoginRequest message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        LoginRequest.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a LoginRequest message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.LoginRequest
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.LoginRequest} LoginRequest
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        LoginRequest.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.LoginRequest();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.username = reader.string();
                        break;
                    }
                case 2: {
                        message.password = reader.bytes();
                        break;
                    }
                case 4: {
                        message.my_id = reader.string();
                        break;
                    }
                case 5: {
                        message.my_name = reader.string();
                        break;
                    }
                case 6: {
                        message.option = $root.hbb.OptionMessage.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 7: {
                        message.file_transfer = $root.hbb.FileTransfer.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 8: {
                        message.port_forward = $root.hbb.PortForward.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 15: {
                        message.view_camera = $root.hbb.ViewCamera.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 9: {
                        message.video_ack_required = reader.bool();
                        break;
                    }
                case 10: {
                        message.session_id = reader.uint64();
                        break;
                    }
                case 11: {
                        message.version = reader.string();
                        break;
                    }
                case 12: {
                        message.os_login = $root.hbb.OSLogin.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 13: {
                        message.my_platform = reader.string();
                        break;
                    }
                case 14: {
                        message.hwid = reader.bytes();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a LoginRequest message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.LoginRequest
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.LoginRequest} LoginRequest
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        LoginRequest.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a LoginRequest message.
         * @function verify
         * @memberof hbb.LoginRequest
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        LoginRequest.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            let properties = {};
            if (message.username != null && message.hasOwnProperty("username"))
                if (!$util.isString(message.username))
                    return "username: string expected";
            if (message.password != null && message.hasOwnProperty("password"))
                if (!(message.password && typeof message.password.length === "number" || $util.isString(message.password)))
                    return "password: buffer expected";
            if (message.my_id != null && message.hasOwnProperty("my_id"))
                if (!$util.isString(message.my_id))
                    return "my_id: string expected";
            if (message.my_name != null && message.hasOwnProperty("my_name"))
                if (!$util.isString(message.my_name))
                    return "my_name: string expected";
            if (message.option != null && message.hasOwnProperty("option")) {
                let error = $root.hbb.OptionMessage.verify(message.option, long + 1);
                if (error)
                    return "option." + error;
            }
            if (message.file_transfer != null && message.hasOwnProperty("file_transfer")) {
                properties.union = 1;
                {
                    let error = $root.hbb.FileTransfer.verify(message.file_transfer, long + 1);
                    if (error)
                        return "file_transfer." + error;
                }
            }
            if (message.port_forward != null && message.hasOwnProperty("port_forward")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.PortForward.verify(message.port_forward, long + 1);
                    if (error)
                        return "port_forward." + error;
                }
            }
            if (message.view_camera != null && message.hasOwnProperty("view_camera")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.ViewCamera.verify(message.view_camera, long + 1);
                    if (error)
                        return "view_camera." + error;
                }
            }
            if (message.video_ack_required != null && message.hasOwnProperty("video_ack_required"))
                if (typeof message.video_ack_required !== "boolean")
                    return "video_ack_required: boolean expected";
            if (message.session_id != null && message.hasOwnProperty("session_id"))
                if (!$util.isInteger(message.session_id) && !(message.session_id && $util.isInteger(message.session_id.low) && $util.isInteger(message.session_id.high)))
                    return "session_id: integer|Long expected";
            if (message.version != null && message.hasOwnProperty("version"))
                if (!$util.isString(message.version))
                    return "version: string expected";
            if (message.os_login != null && message.hasOwnProperty("os_login")) {
                let error = $root.hbb.OSLogin.verify(message.os_login, long + 1);
                if (error)
                    return "os_login." + error;
            }
            if (message.my_platform != null && message.hasOwnProperty("my_platform"))
                if (!$util.isString(message.my_platform))
                    return "my_platform: string expected";
            if (message.hwid != null && message.hasOwnProperty("hwid"))
                if (!(message.hwid && typeof message.hwid.length === "number" || $util.isString(message.hwid)))
                    return "hwid: buffer expected";
            return null;
        };

        /**
         * Creates a LoginRequest message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.LoginRequest
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.LoginRequest} LoginRequest
         */
        LoginRequest.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.LoginRequest)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.LoginRequest();
            if (object.username != null)
                message.username = String(object.username);
            if (object.password != null)
                if (typeof object.password === "string")
                    $util.base64.decode(object.password, message.password = $util.newBuffer($util.base64.length(object.password)), 0);
                else if (object.password.length >= 0)
                    message.password = object.password;
            if (object.my_id != null)
                message.my_id = String(object.my_id);
            if (object.my_name != null)
                message.my_name = String(object.my_name);
            if (object.option != null) {
                if (typeof object.option !== "object")
                    throw TypeError(".hbb.LoginRequest.option: object expected");
                message.option = $root.hbb.OptionMessage.fromObject(object.option, long + 1);
            }
            if (object.file_transfer != null) {
                if (typeof object.file_transfer !== "object")
                    throw TypeError(".hbb.LoginRequest.file_transfer: object expected");
                message.file_transfer = $root.hbb.FileTransfer.fromObject(object.file_transfer, long + 1);
            }
            if (object.port_forward != null) {
                if (typeof object.port_forward !== "object")
                    throw TypeError(".hbb.LoginRequest.port_forward: object expected");
                message.port_forward = $root.hbb.PortForward.fromObject(object.port_forward, long + 1);
            }
            if (object.view_camera != null) {
                if (typeof object.view_camera !== "object")
                    throw TypeError(".hbb.LoginRequest.view_camera: object expected");
                message.view_camera = $root.hbb.ViewCamera.fromObject(object.view_camera, long + 1);
            }
            if (object.video_ack_required != null)
                message.video_ack_required = Boolean(object.video_ack_required);
            if (object.session_id != null)
                if ($util.Long)
                    (message.session_id = $util.Long.fromValue(object.session_id)).unsigned = true;
                else if (typeof object.session_id === "string")
                    message.session_id = parseInt(object.session_id, 10);
                else if (typeof object.session_id === "number")
                    message.session_id = object.session_id;
                else if (typeof object.session_id === "object")
                    message.session_id = new $util.LongBits(object.session_id.low >>> 0, object.session_id.high >>> 0).toNumber(true);
            if (object.version != null)
                message.version = String(object.version);
            if (object.os_login != null) {
                if (typeof object.os_login !== "object")
                    throw TypeError(".hbb.LoginRequest.os_login: object expected");
                message.os_login = $root.hbb.OSLogin.fromObject(object.os_login, long + 1);
            }
            if (object.my_platform != null)
                message.my_platform = String(object.my_platform);
            if (object.hwid != null)
                if (typeof object.hwid === "string")
                    $util.base64.decode(object.hwid, message.hwid = $util.newBuffer($util.base64.length(object.hwid)), 0);
                else if (object.hwid.length >= 0)
                    message.hwid = object.hwid;
            return message;
        };

        /**
         * Creates a plain object from a LoginRequest message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.LoginRequest
         * @static
         * @param {hbb.LoginRequest} message LoginRequest
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        LoginRequest.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.username = "";
                if (options.bytes === String)
                    object.password = "";
                else {
                    object.password = [];
                    if (options.bytes !== Array)
                        object.password = $util.newBuffer(object.password);
                }
                object.my_id = "";
                object.my_name = "";
                object.option = null;
                object.video_ack_required = false;
                if ($util.Long) {
                    let long = new $util.Long(0, 0, true);
                    object.session_id = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.session_id = options.longs === String ? "0" : 0;
                object.version = "";
                object.os_login = null;
                object.my_platform = "";
                if (options.bytes === String)
                    object.hwid = "";
                else {
                    object.hwid = [];
                    if (options.bytes !== Array)
                        object.hwid = $util.newBuffer(object.hwid);
                }
            }
            if (message.username != null && message.hasOwnProperty("username"))
                object.username = message.username;
            if (message.password != null && message.hasOwnProperty("password"))
                object.password = options.bytes === String ? $util.base64.encode(message.password, 0, message.password.length) : options.bytes === Array ? Array.prototype.slice.call(message.password) : message.password;
            if (message.my_id != null && message.hasOwnProperty("my_id"))
                object.my_id = message.my_id;
            if (message.my_name != null && message.hasOwnProperty("my_name"))
                object.my_name = message.my_name;
            if (message.option != null && message.hasOwnProperty("option"))
                object.option = $root.hbb.OptionMessage.toObject(message.option, options);
            if (message.file_transfer != null && message.hasOwnProperty("file_transfer")) {
                object.file_transfer = $root.hbb.FileTransfer.toObject(message.file_transfer, options);
                if (options.oneofs)
                    object.union = "file_transfer";
            }
            if (message.port_forward != null && message.hasOwnProperty("port_forward")) {
                object.port_forward = $root.hbb.PortForward.toObject(message.port_forward, options);
                if (options.oneofs)
                    object.union = "port_forward";
            }
            if (message.video_ack_required != null && message.hasOwnProperty("video_ack_required"))
                object.video_ack_required = message.video_ack_required;
            if (message.session_id != null && message.hasOwnProperty("session_id"))
                if (typeof message.session_id === "number")
                    object.session_id = options.longs === String ? String(message.session_id) : message.session_id;
                else
                    object.session_id = options.longs === String ? $util.Long.prototype.toString.call(message.session_id) : options.longs === Number ? new $util.LongBits(message.session_id.low >>> 0, message.session_id.high >>> 0).toNumber(true) : message.session_id;
            if (message.version != null && message.hasOwnProperty("version"))
                object.version = message.version;
            if (message.os_login != null && message.hasOwnProperty("os_login"))
                object.os_login = $root.hbb.OSLogin.toObject(message.os_login, options);
            if (message.my_platform != null && message.hasOwnProperty("my_platform"))
                object.my_platform = message.my_platform;
            if (message.hwid != null && message.hasOwnProperty("hwid"))
                object.hwid = options.bytes === String ? $util.base64.encode(message.hwid, 0, message.hwid.length) : options.bytes === Array ? Array.prototype.slice.call(message.hwid) : message.hwid;
            if (message.view_camera != null && message.hasOwnProperty("view_camera")) {
                object.view_camera = $root.hbb.ViewCamera.toObject(message.view_camera, options);
                if (options.oneofs)
                    object.union = "view_camera";
            }
            return object;
        };

        /**
         * Converts this LoginRequest to JSON.
         * @function toJSON
         * @memberof hbb.LoginRequest
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        LoginRequest.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for LoginRequest
         * @function getTypeUrl
         * @memberof hbb.LoginRequest
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        LoginRequest.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.LoginRequest";
        };

        return LoginRequest;
    })();

    hbb.Auth2FA = (function() {

        /**
         * Properties of an Auth2FA.
         * @memberof hbb
         * @interface IAuth2FA
         * @property {string|null} [code] Auth2FA code
         * @property {Uint8Array|null} [hwid] Auth2FA hwid
         */

        /**
         * Constructs a new Auth2FA.
         * @memberof hbb
         * @classdesc Represents an Auth2FA.
         * @implements IAuth2FA
         * @constructor
         * @param {hbb.IAuth2FA=} [properties] Properties to set
         */
        function Auth2FA(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * Auth2FA code.
         * @member {string} code
         * @memberof hbb.Auth2FA
         * @instance
         */
        Auth2FA.prototype.code = "";

        /**
         * Auth2FA hwid.
         * @member {Uint8Array} hwid
         * @memberof hbb.Auth2FA
         * @instance
         */
        Auth2FA.prototype.hwid = $util.newBuffer([]);

        /**
         * Creates a new Auth2FA instance using the specified properties.
         * @function create
         * @memberof hbb.Auth2FA
         * @static
         * @param {hbb.IAuth2FA=} [properties] Properties to set
         * @returns {hbb.Auth2FA} Auth2FA instance
         */
        Auth2FA.create = function create(properties) {
            return new Auth2FA(properties);
        };

        /**
         * Encodes the specified Auth2FA message. Does not implicitly {@link hbb.Auth2FA.verify|verify} messages.
         * @function encode
         * @memberof hbb.Auth2FA
         * @static
         * @param {hbb.IAuth2FA} message Auth2FA message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Auth2FA.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.code != null && Object.hasOwnProperty.call(message, "code"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.code);
            if (message.hwid != null && Object.hasOwnProperty.call(message, "hwid"))
                writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.hwid);
            return writer;
        };

        /**
         * Encodes the specified Auth2FA message, length delimited. Does not implicitly {@link hbb.Auth2FA.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.Auth2FA
         * @static
         * @param {hbb.IAuth2FA} message Auth2FA message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Auth2FA.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an Auth2FA message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.Auth2FA
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.Auth2FA} Auth2FA
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Auth2FA.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.Auth2FA();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.code = reader.string();
                        break;
                    }
                case 2: {
                        message.hwid = reader.bytes();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an Auth2FA message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.Auth2FA
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.Auth2FA} Auth2FA
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Auth2FA.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an Auth2FA message.
         * @function verify
         * @memberof hbb.Auth2FA
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        Auth2FA.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.code != null && message.hasOwnProperty("code"))
                if (!$util.isString(message.code))
                    return "code: string expected";
            if (message.hwid != null && message.hasOwnProperty("hwid"))
                if (!(message.hwid && typeof message.hwid.length === "number" || $util.isString(message.hwid)))
                    return "hwid: buffer expected";
            return null;
        };

        /**
         * Creates an Auth2FA message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.Auth2FA
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.Auth2FA} Auth2FA
         */
        Auth2FA.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.Auth2FA)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.Auth2FA();
            if (object.code != null)
                message.code = String(object.code);
            if (object.hwid != null)
                if (typeof object.hwid === "string")
                    $util.base64.decode(object.hwid, message.hwid = $util.newBuffer($util.base64.length(object.hwid)), 0);
                else if (object.hwid.length >= 0)
                    message.hwid = object.hwid;
            return message;
        };

        /**
         * Creates a plain object from an Auth2FA message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.Auth2FA
         * @static
         * @param {hbb.Auth2FA} message Auth2FA
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        Auth2FA.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.code = "";
                if (options.bytes === String)
                    object.hwid = "";
                else {
                    object.hwid = [];
                    if (options.bytes !== Array)
                        object.hwid = $util.newBuffer(object.hwid);
                }
            }
            if (message.code != null && message.hasOwnProperty("code"))
                object.code = message.code;
            if (message.hwid != null && message.hasOwnProperty("hwid"))
                object.hwid = options.bytes === String ? $util.base64.encode(message.hwid, 0, message.hwid.length) : options.bytes === Array ? Array.prototype.slice.call(message.hwid) : message.hwid;
            return object;
        };

        /**
         * Converts this Auth2FA to JSON.
         * @function toJSON
         * @memberof hbb.Auth2FA
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        Auth2FA.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for Auth2FA
         * @function getTypeUrl
         * @memberof hbb.Auth2FA
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        Auth2FA.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.Auth2FA";
        };

        return Auth2FA;
    })();

    hbb.ChatMessage = (function() {

        /**
         * Properties of a ChatMessage.
         * @memberof hbb
         * @interface IChatMessage
         * @property {string|null} [text] ChatMessage text
         */

        /**
         * Constructs a new ChatMessage.
         * @memberof hbb
         * @classdesc Represents a ChatMessage.
         * @implements IChatMessage
         * @constructor
         * @param {hbb.IChatMessage=} [properties] Properties to set
         */
        function ChatMessage(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ChatMessage text.
         * @member {string} text
         * @memberof hbb.ChatMessage
         * @instance
         */
        ChatMessage.prototype.text = "";

        /**
         * Creates a new ChatMessage instance using the specified properties.
         * @function create
         * @memberof hbb.ChatMessage
         * @static
         * @param {hbb.IChatMessage=} [properties] Properties to set
         * @returns {hbb.ChatMessage} ChatMessage instance
         */
        ChatMessage.create = function create(properties) {
            return new ChatMessage(properties);
        };

        /**
         * Encodes the specified ChatMessage message. Does not implicitly {@link hbb.ChatMessage.verify|verify} messages.
         * @function encode
         * @memberof hbb.ChatMessage
         * @static
         * @param {hbb.IChatMessage} message ChatMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ChatMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.text != null && Object.hasOwnProperty.call(message, "text"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.text);
            return writer;
        };

        /**
         * Encodes the specified ChatMessage message, length delimited. Does not implicitly {@link hbb.ChatMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.ChatMessage
         * @static
         * @param {hbb.IChatMessage} message ChatMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ChatMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a ChatMessage message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.ChatMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.ChatMessage} ChatMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ChatMessage.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.ChatMessage();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.text = reader.string();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a ChatMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.ChatMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.ChatMessage} ChatMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ChatMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a ChatMessage message.
         * @function verify
         * @memberof hbb.ChatMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ChatMessage.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.text != null && message.hasOwnProperty("text"))
                if (!$util.isString(message.text))
                    return "text: string expected";
            return null;
        };

        /**
         * Creates a ChatMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.ChatMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.ChatMessage} ChatMessage
         */
        ChatMessage.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.ChatMessage)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.ChatMessage();
            if (object.text != null)
                message.text = String(object.text);
            return message;
        };

        /**
         * Creates a plain object from a ChatMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.ChatMessage
         * @static
         * @param {hbb.ChatMessage} message ChatMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ChatMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults)
                object.text = "";
            if (message.text != null && message.hasOwnProperty("text"))
                object.text = message.text;
            return object;
        };

        /**
         * Converts this ChatMessage to JSON.
         * @function toJSON
         * @memberof hbb.ChatMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ChatMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for ChatMessage
         * @function getTypeUrl
         * @memberof hbb.ChatMessage
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        ChatMessage.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.ChatMessage";
        };

        return ChatMessage;
    })();

    hbb.Features = (function() {

        /**
         * Properties of a Features.
         * @memberof hbb
         * @interface IFeatures
         * @property {boolean|null} [privacy_mode] Features privacy_mode
         */

        /**
         * Constructs a new Features.
         * @memberof hbb
         * @classdesc Represents a Features.
         * @implements IFeatures
         * @constructor
         * @param {hbb.IFeatures=} [properties] Properties to set
         */
        function Features(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * Features privacy_mode.
         * @member {boolean} privacy_mode
         * @memberof hbb.Features
         * @instance
         */
        Features.prototype.privacy_mode = false;

        /**
         * Creates a new Features instance using the specified properties.
         * @function create
         * @memberof hbb.Features
         * @static
         * @param {hbb.IFeatures=} [properties] Properties to set
         * @returns {hbb.Features} Features instance
         */
        Features.create = function create(properties) {
            return new Features(properties);
        };

        /**
         * Encodes the specified Features message. Does not implicitly {@link hbb.Features.verify|verify} messages.
         * @function encode
         * @memberof hbb.Features
         * @static
         * @param {hbb.IFeatures} message Features message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Features.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.privacy_mode != null && Object.hasOwnProperty.call(message, "privacy_mode"))
                writer.uint32(/* id 1, wireType 0 =*/8).bool(message.privacy_mode);
            return writer;
        };

        /**
         * Encodes the specified Features message, length delimited. Does not implicitly {@link hbb.Features.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.Features
         * @static
         * @param {hbb.IFeatures} message Features message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Features.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a Features message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.Features
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.Features} Features
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Features.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.Features();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.privacy_mode = reader.bool();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a Features message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.Features
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.Features} Features
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Features.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a Features message.
         * @function verify
         * @memberof hbb.Features
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        Features.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.privacy_mode != null && message.hasOwnProperty("privacy_mode"))
                if (typeof message.privacy_mode !== "boolean")
                    return "privacy_mode: boolean expected";
            return null;
        };

        /**
         * Creates a Features message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.Features
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.Features} Features
         */
        Features.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.Features)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.Features();
            if (object.privacy_mode != null)
                message.privacy_mode = Boolean(object.privacy_mode);
            return message;
        };

        /**
         * Creates a plain object from a Features message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.Features
         * @static
         * @param {hbb.Features} message Features
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        Features.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults)
                object.privacy_mode = false;
            if (message.privacy_mode != null && message.hasOwnProperty("privacy_mode"))
                object.privacy_mode = message.privacy_mode;
            return object;
        };

        /**
         * Converts this Features to JSON.
         * @function toJSON
         * @memberof hbb.Features
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        Features.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for Features
         * @function getTypeUrl
         * @memberof hbb.Features
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        Features.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.Features";
        };

        return Features;
    })();

    hbb.CodecAbility = (function() {

        /**
         * Properties of a CodecAbility.
         * @memberof hbb
         * @interface ICodecAbility
         * @property {boolean|null} [vp8] CodecAbility vp8
         * @property {boolean|null} [vp9] CodecAbility vp9
         * @property {boolean|null} [av1] CodecAbility av1
         * @property {boolean|null} [h264] CodecAbility h264
         * @property {boolean|null} [h265] CodecAbility h265
         */

        /**
         * Constructs a new CodecAbility.
         * @memberof hbb
         * @classdesc Represents a CodecAbility.
         * @implements ICodecAbility
         * @constructor
         * @param {hbb.ICodecAbility=} [properties] Properties to set
         */
        function CodecAbility(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * CodecAbility vp8.
         * @member {boolean} vp8
         * @memberof hbb.CodecAbility
         * @instance
         */
        CodecAbility.prototype.vp8 = false;

        /**
         * CodecAbility vp9.
         * @member {boolean} vp9
         * @memberof hbb.CodecAbility
         * @instance
         */
        CodecAbility.prototype.vp9 = false;

        /**
         * CodecAbility av1.
         * @member {boolean} av1
         * @memberof hbb.CodecAbility
         * @instance
         */
        CodecAbility.prototype.av1 = false;

        /**
         * CodecAbility h264.
         * @member {boolean} h264
         * @memberof hbb.CodecAbility
         * @instance
         */
        CodecAbility.prototype.h264 = false;

        /**
         * CodecAbility h265.
         * @member {boolean} h265
         * @memberof hbb.CodecAbility
         * @instance
         */
        CodecAbility.prototype.h265 = false;

        /**
         * Creates a new CodecAbility instance using the specified properties.
         * @function create
         * @memberof hbb.CodecAbility
         * @static
         * @param {hbb.ICodecAbility=} [properties] Properties to set
         * @returns {hbb.CodecAbility} CodecAbility instance
         */
        CodecAbility.create = function create(properties) {
            return new CodecAbility(properties);
        };

        /**
         * Encodes the specified CodecAbility message. Does not implicitly {@link hbb.CodecAbility.verify|verify} messages.
         * @function encode
         * @memberof hbb.CodecAbility
         * @static
         * @param {hbb.ICodecAbility} message CodecAbility message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CodecAbility.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.vp8 != null && Object.hasOwnProperty.call(message, "vp8"))
                writer.uint32(/* id 1, wireType 0 =*/8).bool(message.vp8);
            if (message.vp9 != null && Object.hasOwnProperty.call(message, "vp9"))
                writer.uint32(/* id 2, wireType 0 =*/16).bool(message.vp9);
            if (message.av1 != null && Object.hasOwnProperty.call(message, "av1"))
                writer.uint32(/* id 3, wireType 0 =*/24).bool(message.av1);
            if (message.h264 != null && Object.hasOwnProperty.call(message, "h264"))
                writer.uint32(/* id 4, wireType 0 =*/32).bool(message.h264);
            if (message.h265 != null && Object.hasOwnProperty.call(message, "h265"))
                writer.uint32(/* id 5, wireType 0 =*/40).bool(message.h265);
            return writer;
        };

        /**
         * Encodes the specified CodecAbility message, length delimited. Does not implicitly {@link hbb.CodecAbility.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.CodecAbility
         * @static
         * @param {hbb.ICodecAbility} message CodecAbility message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CodecAbility.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a CodecAbility message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.CodecAbility
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.CodecAbility} CodecAbility
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CodecAbility.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.CodecAbility();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.vp8 = reader.bool();
                        break;
                    }
                case 2: {
                        message.vp9 = reader.bool();
                        break;
                    }
                case 3: {
                        message.av1 = reader.bool();
                        break;
                    }
                case 4: {
                        message.h264 = reader.bool();
                        break;
                    }
                case 5: {
                        message.h265 = reader.bool();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a CodecAbility message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.CodecAbility
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.CodecAbility} CodecAbility
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CodecAbility.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a CodecAbility message.
         * @function verify
         * @memberof hbb.CodecAbility
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        CodecAbility.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.vp8 != null && message.hasOwnProperty("vp8"))
                if (typeof message.vp8 !== "boolean")
                    return "vp8: boolean expected";
            if (message.vp9 != null && message.hasOwnProperty("vp9"))
                if (typeof message.vp9 !== "boolean")
                    return "vp9: boolean expected";
            if (message.av1 != null && message.hasOwnProperty("av1"))
                if (typeof message.av1 !== "boolean")
                    return "av1: boolean expected";
            if (message.h264 != null && message.hasOwnProperty("h264"))
                if (typeof message.h264 !== "boolean")
                    return "h264: boolean expected";
            if (message.h265 != null && message.hasOwnProperty("h265"))
                if (typeof message.h265 !== "boolean")
                    return "h265: boolean expected";
            return null;
        };

        /**
         * Creates a CodecAbility message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.CodecAbility
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.CodecAbility} CodecAbility
         */
        CodecAbility.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.CodecAbility)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.CodecAbility();
            if (object.vp8 != null)
                message.vp8 = Boolean(object.vp8);
            if (object.vp9 != null)
                message.vp9 = Boolean(object.vp9);
            if (object.av1 != null)
                message.av1 = Boolean(object.av1);
            if (object.h264 != null)
                message.h264 = Boolean(object.h264);
            if (object.h265 != null)
                message.h265 = Boolean(object.h265);
            return message;
        };

        /**
         * Creates a plain object from a CodecAbility message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.CodecAbility
         * @static
         * @param {hbb.CodecAbility} message CodecAbility
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        CodecAbility.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.vp8 = false;
                object.vp9 = false;
                object.av1 = false;
                object.h264 = false;
                object.h265 = false;
            }
            if (message.vp8 != null && message.hasOwnProperty("vp8"))
                object.vp8 = message.vp8;
            if (message.vp9 != null && message.hasOwnProperty("vp9"))
                object.vp9 = message.vp9;
            if (message.av1 != null && message.hasOwnProperty("av1"))
                object.av1 = message.av1;
            if (message.h264 != null && message.hasOwnProperty("h264"))
                object.h264 = message.h264;
            if (message.h265 != null && message.hasOwnProperty("h265"))
                object.h265 = message.h265;
            return object;
        };

        /**
         * Converts this CodecAbility to JSON.
         * @function toJSON
         * @memberof hbb.CodecAbility
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        CodecAbility.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for CodecAbility
         * @function getTypeUrl
         * @memberof hbb.CodecAbility
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        CodecAbility.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.CodecAbility";
        };

        return CodecAbility;
    })();

    hbb.SupportedEncoding = (function() {

        /**
         * Properties of a SupportedEncoding.
         * @memberof hbb
         * @interface ISupportedEncoding
         * @property {boolean|null} [h264] SupportedEncoding h264
         * @property {boolean|null} [h265] SupportedEncoding h265
         * @property {boolean|null} [vp8] SupportedEncoding vp8
         * @property {boolean|null} [av1] SupportedEncoding av1
         * @property {hbb.ICodecAbility|null} [i444] SupportedEncoding i444
         */

        /**
         * Constructs a new SupportedEncoding.
         * @memberof hbb
         * @classdesc Represents a SupportedEncoding.
         * @implements ISupportedEncoding
         * @constructor
         * @param {hbb.ISupportedEncoding=} [properties] Properties to set
         */
        function SupportedEncoding(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * SupportedEncoding h264.
         * @member {boolean} h264
         * @memberof hbb.SupportedEncoding
         * @instance
         */
        SupportedEncoding.prototype.h264 = false;

        /**
         * SupportedEncoding h265.
         * @member {boolean} h265
         * @memberof hbb.SupportedEncoding
         * @instance
         */
        SupportedEncoding.prototype.h265 = false;

        /**
         * SupportedEncoding vp8.
         * @member {boolean} vp8
         * @memberof hbb.SupportedEncoding
         * @instance
         */
        SupportedEncoding.prototype.vp8 = false;

        /**
         * SupportedEncoding av1.
         * @member {boolean} av1
         * @memberof hbb.SupportedEncoding
         * @instance
         */
        SupportedEncoding.prototype.av1 = false;

        /**
         * SupportedEncoding i444.
         * @member {hbb.ICodecAbility|null|undefined} i444
         * @memberof hbb.SupportedEncoding
         * @instance
         */
        SupportedEncoding.prototype.i444 = null;

        /**
         * Creates a new SupportedEncoding instance using the specified properties.
         * @function create
         * @memberof hbb.SupportedEncoding
         * @static
         * @param {hbb.ISupportedEncoding=} [properties] Properties to set
         * @returns {hbb.SupportedEncoding} SupportedEncoding instance
         */
        SupportedEncoding.create = function create(properties) {
            return new SupportedEncoding(properties);
        };

        /**
         * Encodes the specified SupportedEncoding message. Does not implicitly {@link hbb.SupportedEncoding.verify|verify} messages.
         * @function encode
         * @memberof hbb.SupportedEncoding
         * @static
         * @param {hbb.ISupportedEncoding} message SupportedEncoding message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SupportedEncoding.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.h264 != null && Object.hasOwnProperty.call(message, "h264"))
                writer.uint32(/* id 1, wireType 0 =*/8).bool(message.h264);
            if (message.h265 != null && Object.hasOwnProperty.call(message, "h265"))
                writer.uint32(/* id 2, wireType 0 =*/16).bool(message.h265);
            if (message.vp8 != null && Object.hasOwnProperty.call(message, "vp8"))
                writer.uint32(/* id 3, wireType 0 =*/24).bool(message.vp8);
            if (message.av1 != null && Object.hasOwnProperty.call(message, "av1"))
                writer.uint32(/* id 4, wireType 0 =*/32).bool(message.av1);
            if (message.i444 != null && Object.hasOwnProperty.call(message, "i444"))
                $root.hbb.CodecAbility.encode(message.i444, writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified SupportedEncoding message, length delimited. Does not implicitly {@link hbb.SupportedEncoding.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.SupportedEncoding
         * @static
         * @param {hbb.ISupportedEncoding} message SupportedEncoding message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SupportedEncoding.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a SupportedEncoding message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.SupportedEncoding
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.SupportedEncoding} SupportedEncoding
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SupportedEncoding.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.SupportedEncoding();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.h264 = reader.bool();
                        break;
                    }
                case 2: {
                        message.h265 = reader.bool();
                        break;
                    }
                case 3: {
                        message.vp8 = reader.bool();
                        break;
                    }
                case 4: {
                        message.av1 = reader.bool();
                        break;
                    }
                case 5: {
                        message.i444 = $root.hbb.CodecAbility.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a SupportedEncoding message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.SupportedEncoding
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.SupportedEncoding} SupportedEncoding
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SupportedEncoding.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a SupportedEncoding message.
         * @function verify
         * @memberof hbb.SupportedEncoding
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        SupportedEncoding.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.h264 != null && message.hasOwnProperty("h264"))
                if (typeof message.h264 !== "boolean")
                    return "h264: boolean expected";
            if (message.h265 != null && message.hasOwnProperty("h265"))
                if (typeof message.h265 !== "boolean")
                    return "h265: boolean expected";
            if (message.vp8 != null && message.hasOwnProperty("vp8"))
                if (typeof message.vp8 !== "boolean")
                    return "vp8: boolean expected";
            if (message.av1 != null && message.hasOwnProperty("av1"))
                if (typeof message.av1 !== "boolean")
                    return "av1: boolean expected";
            if (message.i444 != null && message.hasOwnProperty("i444")) {
                let error = $root.hbb.CodecAbility.verify(message.i444, long + 1);
                if (error)
                    return "i444." + error;
            }
            return null;
        };

        /**
         * Creates a SupportedEncoding message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.SupportedEncoding
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.SupportedEncoding} SupportedEncoding
         */
        SupportedEncoding.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.SupportedEncoding)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.SupportedEncoding();
            if (object.h264 != null)
                message.h264 = Boolean(object.h264);
            if (object.h265 != null)
                message.h265 = Boolean(object.h265);
            if (object.vp8 != null)
                message.vp8 = Boolean(object.vp8);
            if (object.av1 != null)
                message.av1 = Boolean(object.av1);
            if (object.i444 != null) {
                if (typeof object.i444 !== "object")
                    throw TypeError(".hbb.SupportedEncoding.i444: object expected");
                message.i444 = $root.hbb.CodecAbility.fromObject(object.i444, long + 1);
            }
            return message;
        };

        /**
         * Creates a plain object from a SupportedEncoding message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.SupportedEncoding
         * @static
         * @param {hbb.SupportedEncoding} message SupportedEncoding
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        SupportedEncoding.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.h264 = false;
                object.h265 = false;
                object.vp8 = false;
                object.av1 = false;
                object.i444 = null;
            }
            if (message.h264 != null && message.hasOwnProperty("h264"))
                object.h264 = message.h264;
            if (message.h265 != null && message.hasOwnProperty("h265"))
                object.h265 = message.h265;
            if (message.vp8 != null && message.hasOwnProperty("vp8"))
                object.vp8 = message.vp8;
            if (message.av1 != null && message.hasOwnProperty("av1"))
                object.av1 = message.av1;
            if (message.i444 != null && message.hasOwnProperty("i444"))
                object.i444 = $root.hbb.CodecAbility.toObject(message.i444, options);
            return object;
        };

        /**
         * Converts this SupportedEncoding to JSON.
         * @function toJSON
         * @memberof hbb.SupportedEncoding
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        SupportedEncoding.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for SupportedEncoding
         * @function getTypeUrl
         * @memberof hbb.SupportedEncoding
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        SupportedEncoding.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.SupportedEncoding";
        };

        return SupportedEncoding;
    })();

    hbb.PeerInfo = (function() {

        /**
         * Properties of a PeerInfo.
         * @memberof hbb
         * @interface IPeerInfo
         * @property {string|null} [username] PeerInfo username
         * @property {string|null} [hostname] PeerInfo hostname
         * @property {string|null} [platform] PeerInfo platform
         * @property {Array.<hbb.IDisplayInfo>|null} [displays] PeerInfo displays
         * @property {number|null} [current_display] PeerInfo current_display
         * @property {boolean|null} [sas_enabled] PeerInfo sas_enabled
         * @property {string|null} [version] PeerInfo version
         * @property {hbb.IFeatures|null} [features] PeerInfo features
         * @property {hbb.ISupportedEncoding|null} [encoding] PeerInfo encoding
         * @property {hbb.ISupportedResolutions|null} [resolutions] PeerInfo resolutions
         * @property {string|null} [platform_additions] PeerInfo platform_additions
         * @property {hbb.IWindowsSessions|null} [windows_sessions] PeerInfo windows_sessions
         */

        /**
         * Constructs a new PeerInfo.
         * @memberof hbb
         * @classdesc Represents a PeerInfo.
         * @implements IPeerInfo
         * @constructor
         * @param {hbb.IPeerInfo=} [properties] Properties to set
         */
        function PeerInfo(properties) {
            this.displays = [];
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * PeerInfo username.
         * @member {string} username
         * @memberof hbb.PeerInfo
         * @instance
         */
        PeerInfo.prototype.username = "";

        /**
         * PeerInfo hostname.
         * @member {string} hostname
         * @memberof hbb.PeerInfo
         * @instance
         */
        PeerInfo.prototype.hostname = "";

        /**
         * PeerInfo platform.
         * @member {string} platform
         * @memberof hbb.PeerInfo
         * @instance
         */
        PeerInfo.prototype.platform = "";

        /**
         * PeerInfo displays.
         * @member {Array.<hbb.IDisplayInfo>} displays
         * @memberof hbb.PeerInfo
         * @instance
         */
        PeerInfo.prototype.displays = $util.emptyArray;

        /**
         * PeerInfo current_display.
         * @member {number} current_display
         * @memberof hbb.PeerInfo
         * @instance
         */
        PeerInfo.prototype.current_display = 0;

        /**
         * PeerInfo sas_enabled.
         * @member {boolean} sas_enabled
         * @memberof hbb.PeerInfo
         * @instance
         */
        PeerInfo.prototype.sas_enabled = false;

        /**
         * PeerInfo version.
         * @member {string} version
         * @memberof hbb.PeerInfo
         * @instance
         */
        PeerInfo.prototype.version = "";

        /**
         * PeerInfo features.
         * @member {hbb.IFeatures|null|undefined} features
         * @memberof hbb.PeerInfo
         * @instance
         */
        PeerInfo.prototype.features = null;

        /**
         * PeerInfo encoding.
         * @member {hbb.ISupportedEncoding|null|undefined} encoding
         * @memberof hbb.PeerInfo
         * @instance
         */
        PeerInfo.prototype.encoding = null;

        /**
         * PeerInfo resolutions.
         * @member {hbb.ISupportedResolutions|null|undefined} resolutions
         * @memberof hbb.PeerInfo
         * @instance
         */
        PeerInfo.prototype.resolutions = null;

        /**
         * PeerInfo platform_additions.
         * @member {string} platform_additions
         * @memberof hbb.PeerInfo
         * @instance
         */
        PeerInfo.prototype.platform_additions = "";

        /**
         * PeerInfo windows_sessions.
         * @member {hbb.IWindowsSessions|null|undefined} windows_sessions
         * @memberof hbb.PeerInfo
         * @instance
         */
        PeerInfo.prototype.windows_sessions = null;

        /**
         * Creates a new PeerInfo instance using the specified properties.
         * @function create
         * @memberof hbb.PeerInfo
         * @static
         * @param {hbb.IPeerInfo=} [properties] Properties to set
         * @returns {hbb.PeerInfo} PeerInfo instance
         */
        PeerInfo.create = function create(properties) {
            return new PeerInfo(properties);
        };

        /**
         * Encodes the specified PeerInfo message. Does not implicitly {@link hbb.PeerInfo.verify|verify} messages.
         * @function encode
         * @memberof hbb.PeerInfo
         * @static
         * @param {hbb.IPeerInfo} message PeerInfo message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        PeerInfo.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.username != null && Object.hasOwnProperty.call(message, "username"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.username);
            if (message.hostname != null && Object.hasOwnProperty.call(message, "hostname"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.hostname);
            if (message.platform != null && Object.hasOwnProperty.call(message, "platform"))
                writer.uint32(/* id 3, wireType 2 =*/26).string(message.platform);
            if (message.displays != null && message.displays.length)
                for (let i = 0; i < message.displays.length; ++i)
                    $root.hbb.DisplayInfo.encode(message.displays[i], writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim();
            if (message.current_display != null && Object.hasOwnProperty.call(message, "current_display"))
                writer.uint32(/* id 5, wireType 0 =*/40).int32(message.current_display);
            if (message.sas_enabled != null && Object.hasOwnProperty.call(message, "sas_enabled"))
                writer.uint32(/* id 6, wireType 0 =*/48).bool(message.sas_enabled);
            if (message.version != null && Object.hasOwnProperty.call(message, "version"))
                writer.uint32(/* id 7, wireType 2 =*/58).string(message.version);
            if (message.features != null && Object.hasOwnProperty.call(message, "features"))
                $root.hbb.Features.encode(message.features, writer.uint32(/* id 9, wireType 2 =*/74).fork()).ldelim();
            if (message.encoding != null && Object.hasOwnProperty.call(message, "encoding"))
                $root.hbb.SupportedEncoding.encode(message.encoding, writer.uint32(/* id 10, wireType 2 =*/82).fork()).ldelim();
            if (message.resolutions != null && Object.hasOwnProperty.call(message, "resolutions"))
                $root.hbb.SupportedResolutions.encode(message.resolutions, writer.uint32(/* id 11, wireType 2 =*/90).fork()).ldelim();
            if (message.platform_additions != null && Object.hasOwnProperty.call(message, "platform_additions"))
                writer.uint32(/* id 12, wireType 2 =*/98).string(message.platform_additions);
            if (message.windows_sessions != null && Object.hasOwnProperty.call(message, "windows_sessions"))
                $root.hbb.WindowsSessions.encode(message.windows_sessions, writer.uint32(/* id 13, wireType 2 =*/106).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified PeerInfo message, length delimited. Does not implicitly {@link hbb.PeerInfo.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.PeerInfo
         * @static
         * @param {hbb.IPeerInfo} message PeerInfo message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        PeerInfo.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a PeerInfo message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.PeerInfo
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.PeerInfo} PeerInfo
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        PeerInfo.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.PeerInfo();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.username = reader.string();
                        break;
                    }
                case 2: {
                        message.hostname = reader.string();
                        break;
                    }
                case 3: {
                        message.platform = reader.string();
                        break;
                    }
                case 4: {
                        if (!(message.displays && message.displays.length))
                            message.displays = [];
                        message.displays.push($root.hbb.DisplayInfo.decode(reader, reader.uint32(), undefined, long + 1));
                        break;
                    }
                case 5: {
                        message.current_display = reader.int32();
                        break;
                    }
                case 6: {
                        message.sas_enabled = reader.bool();
                        break;
                    }
                case 7: {
                        message.version = reader.string();
                        break;
                    }
                case 9: {
                        message.features = $root.hbb.Features.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 10: {
                        message.encoding = $root.hbb.SupportedEncoding.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 11: {
                        message.resolutions = $root.hbb.SupportedResolutions.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 12: {
                        message.platform_additions = reader.string();
                        break;
                    }
                case 13: {
                        message.windows_sessions = $root.hbb.WindowsSessions.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a PeerInfo message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.PeerInfo
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.PeerInfo} PeerInfo
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        PeerInfo.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a PeerInfo message.
         * @function verify
         * @memberof hbb.PeerInfo
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        PeerInfo.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.username != null && message.hasOwnProperty("username"))
                if (!$util.isString(message.username))
                    return "username: string expected";
            if (message.hostname != null && message.hasOwnProperty("hostname"))
                if (!$util.isString(message.hostname))
                    return "hostname: string expected";
            if (message.platform != null && message.hasOwnProperty("platform"))
                if (!$util.isString(message.platform))
                    return "platform: string expected";
            if (message.displays != null && message.hasOwnProperty("displays")) {
                if (!Array.isArray(message.displays))
                    return "displays: array expected";
                for (let i = 0; i < message.displays.length; ++i) {
                    let error = $root.hbb.DisplayInfo.verify(message.displays[i], long + 1);
                    if (error)
                        return "displays." + error;
                }
            }
            if (message.current_display != null && message.hasOwnProperty("current_display"))
                if (!$util.isInteger(message.current_display))
                    return "current_display: integer expected";
            if (message.sas_enabled != null && message.hasOwnProperty("sas_enabled"))
                if (typeof message.sas_enabled !== "boolean")
                    return "sas_enabled: boolean expected";
            if (message.version != null && message.hasOwnProperty("version"))
                if (!$util.isString(message.version))
                    return "version: string expected";
            if (message.features != null && message.hasOwnProperty("features")) {
                let error = $root.hbb.Features.verify(message.features, long + 1);
                if (error)
                    return "features." + error;
            }
            if (message.encoding != null && message.hasOwnProperty("encoding")) {
                let error = $root.hbb.SupportedEncoding.verify(message.encoding, long + 1);
                if (error)
                    return "encoding." + error;
            }
            if (message.resolutions != null && message.hasOwnProperty("resolutions")) {
                let error = $root.hbb.SupportedResolutions.verify(message.resolutions, long + 1);
                if (error)
                    return "resolutions." + error;
            }
            if (message.platform_additions != null && message.hasOwnProperty("platform_additions"))
                if (!$util.isString(message.platform_additions))
                    return "platform_additions: string expected";
            if (message.windows_sessions != null && message.hasOwnProperty("windows_sessions")) {
                let error = $root.hbb.WindowsSessions.verify(message.windows_sessions, long + 1);
                if (error)
                    return "windows_sessions." + error;
            }
            return null;
        };

        /**
         * Creates a PeerInfo message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.PeerInfo
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.PeerInfo} PeerInfo
         */
        PeerInfo.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.PeerInfo)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.PeerInfo();
            if (object.username != null)
                message.username = String(object.username);
            if (object.hostname != null)
                message.hostname = String(object.hostname);
            if (object.platform != null)
                message.platform = String(object.platform);
            if (object.displays) {
                if (!Array.isArray(object.displays))
                    throw TypeError(".hbb.PeerInfo.displays: array expected");
                message.displays = [];
                for (let i = 0; i < object.displays.length; ++i) {
                    if (typeof object.displays[i] !== "object")
                        throw TypeError(".hbb.PeerInfo.displays: object expected");
                    message.displays[i] = $root.hbb.DisplayInfo.fromObject(object.displays[i], long + 1);
                }
            }
            if (object.current_display != null)
                message.current_display = object.current_display | 0;
            if (object.sas_enabled != null)
                message.sas_enabled = Boolean(object.sas_enabled);
            if (object.version != null)
                message.version = String(object.version);
            if (object.features != null) {
                if (typeof object.features !== "object")
                    throw TypeError(".hbb.PeerInfo.features: object expected");
                message.features = $root.hbb.Features.fromObject(object.features, long + 1);
            }
            if (object.encoding != null) {
                if (typeof object.encoding !== "object")
                    throw TypeError(".hbb.PeerInfo.encoding: object expected");
                message.encoding = $root.hbb.SupportedEncoding.fromObject(object.encoding, long + 1);
            }
            if (object.resolutions != null) {
                if (typeof object.resolutions !== "object")
                    throw TypeError(".hbb.PeerInfo.resolutions: object expected");
                message.resolutions = $root.hbb.SupportedResolutions.fromObject(object.resolutions, long + 1);
            }
            if (object.platform_additions != null)
                message.platform_additions = String(object.platform_additions);
            if (object.windows_sessions != null) {
                if (typeof object.windows_sessions !== "object")
                    throw TypeError(".hbb.PeerInfo.windows_sessions: object expected");
                message.windows_sessions = $root.hbb.WindowsSessions.fromObject(object.windows_sessions, long + 1);
            }
            return message;
        };

        /**
         * Creates a plain object from a PeerInfo message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.PeerInfo
         * @static
         * @param {hbb.PeerInfo} message PeerInfo
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        PeerInfo.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.arrays || options.defaults)
                object.displays = [];
            if (options.defaults) {
                object.username = "";
                object.hostname = "";
                object.platform = "";
                object.current_display = 0;
                object.sas_enabled = false;
                object.version = "";
                object.features = null;
                object.encoding = null;
                object.resolutions = null;
                object.platform_additions = "";
                object.windows_sessions = null;
            }
            if (message.username != null && message.hasOwnProperty("username"))
                object.username = message.username;
            if (message.hostname != null && message.hasOwnProperty("hostname"))
                object.hostname = message.hostname;
            if (message.platform != null && message.hasOwnProperty("platform"))
                object.platform = message.platform;
            if (message.displays && message.displays.length) {
                object.displays = [];
                for (let j = 0; j < message.displays.length; ++j)
                    object.displays[j] = $root.hbb.DisplayInfo.toObject(message.displays[j], options);
            }
            if (message.current_display != null && message.hasOwnProperty("current_display"))
                object.current_display = message.current_display;
            if (message.sas_enabled != null && message.hasOwnProperty("sas_enabled"))
                object.sas_enabled = message.sas_enabled;
            if (message.version != null && message.hasOwnProperty("version"))
                object.version = message.version;
            if (message.features != null && message.hasOwnProperty("features"))
                object.features = $root.hbb.Features.toObject(message.features, options);
            if (message.encoding != null && message.hasOwnProperty("encoding"))
                object.encoding = $root.hbb.SupportedEncoding.toObject(message.encoding, options);
            if (message.resolutions != null && message.hasOwnProperty("resolutions"))
                object.resolutions = $root.hbb.SupportedResolutions.toObject(message.resolutions, options);
            if (message.platform_additions != null && message.hasOwnProperty("platform_additions"))
                object.platform_additions = message.platform_additions;
            if (message.windows_sessions != null && message.hasOwnProperty("windows_sessions"))
                object.windows_sessions = $root.hbb.WindowsSessions.toObject(message.windows_sessions, options);
            return object;
        };

        /**
         * Converts this PeerInfo to JSON.
         * @function toJSON
         * @memberof hbb.PeerInfo
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        PeerInfo.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for PeerInfo
         * @function getTypeUrl
         * @memberof hbb.PeerInfo
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        PeerInfo.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.PeerInfo";
        };

        return PeerInfo;
    })();

    hbb.WindowsSession = (function() {

        /**
         * Properties of a WindowsSession.
         * @memberof hbb
         * @interface IWindowsSession
         * @property {number|null} [sid] WindowsSession sid
         * @property {string|null} [name] WindowsSession name
         */

        /**
         * Constructs a new WindowsSession.
         * @memberof hbb
         * @classdesc Represents a WindowsSession.
         * @implements IWindowsSession
         * @constructor
         * @param {hbb.IWindowsSession=} [properties] Properties to set
         */
        function WindowsSession(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * WindowsSession sid.
         * @member {number} sid
         * @memberof hbb.WindowsSession
         * @instance
         */
        WindowsSession.prototype.sid = 0;

        /**
         * WindowsSession name.
         * @member {string} name
         * @memberof hbb.WindowsSession
         * @instance
         */
        WindowsSession.prototype.name = "";

        /**
         * Creates a new WindowsSession instance using the specified properties.
         * @function create
         * @memberof hbb.WindowsSession
         * @static
         * @param {hbb.IWindowsSession=} [properties] Properties to set
         * @returns {hbb.WindowsSession} WindowsSession instance
         */
        WindowsSession.create = function create(properties) {
            return new WindowsSession(properties);
        };

        /**
         * Encodes the specified WindowsSession message. Does not implicitly {@link hbb.WindowsSession.verify|verify} messages.
         * @function encode
         * @memberof hbb.WindowsSession
         * @static
         * @param {hbb.IWindowsSession} message WindowsSession message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        WindowsSession.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.sid != null && Object.hasOwnProperty.call(message, "sid"))
                writer.uint32(/* id 1, wireType 0 =*/8).uint32(message.sid);
            if (message.name != null && Object.hasOwnProperty.call(message, "name"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.name);
            return writer;
        };

        /**
         * Encodes the specified WindowsSession message, length delimited. Does not implicitly {@link hbb.WindowsSession.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.WindowsSession
         * @static
         * @param {hbb.IWindowsSession} message WindowsSession message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        WindowsSession.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a WindowsSession message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.WindowsSession
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.WindowsSession} WindowsSession
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        WindowsSession.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.WindowsSession();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.sid = reader.uint32();
                        break;
                    }
                case 2: {
                        message.name = reader.string();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a WindowsSession message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.WindowsSession
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.WindowsSession} WindowsSession
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        WindowsSession.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a WindowsSession message.
         * @function verify
         * @memberof hbb.WindowsSession
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        WindowsSession.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.sid != null && message.hasOwnProperty("sid"))
                if (!$util.isInteger(message.sid))
                    return "sid: integer expected";
            if (message.name != null && message.hasOwnProperty("name"))
                if (!$util.isString(message.name))
                    return "name: string expected";
            return null;
        };

        /**
         * Creates a WindowsSession message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.WindowsSession
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.WindowsSession} WindowsSession
         */
        WindowsSession.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.WindowsSession)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.WindowsSession();
            if (object.sid != null)
                message.sid = object.sid >>> 0;
            if (object.name != null)
                message.name = String(object.name);
            return message;
        };

        /**
         * Creates a plain object from a WindowsSession message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.WindowsSession
         * @static
         * @param {hbb.WindowsSession} message WindowsSession
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        WindowsSession.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.sid = 0;
                object.name = "";
            }
            if (message.sid != null && message.hasOwnProperty("sid"))
                object.sid = message.sid;
            if (message.name != null && message.hasOwnProperty("name"))
                object.name = message.name;
            return object;
        };

        /**
         * Converts this WindowsSession to JSON.
         * @function toJSON
         * @memberof hbb.WindowsSession
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        WindowsSession.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for WindowsSession
         * @function getTypeUrl
         * @memberof hbb.WindowsSession
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        WindowsSession.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.WindowsSession";
        };

        return WindowsSession;
    })();

    hbb.LoginResponse = (function() {

        /**
         * Properties of a LoginResponse.
         * @memberof hbb
         * @interface ILoginResponse
         * @property {string|null} [error] LoginResponse error
         * @property {hbb.IPeerInfo|null} [peer_info] LoginResponse peer_info
         * @property {boolean|null} [enable_trusted_devices] LoginResponse enable_trusted_devices
         */

        /**
         * Constructs a new LoginResponse.
         * @memberof hbb
         * @classdesc Represents a LoginResponse.
         * @implements ILoginResponse
         * @constructor
         * @param {hbb.ILoginResponse=} [properties] Properties to set
         */
        function LoginResponse(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * LoginResponse error.
         * @member {string|null|undefined} error
         * @memberof hbb.LoginResponse
         * @instance
         */
        LoginResponse.prototype.error = null;

        /**
         * LoginResponse peer_info.
         * @member {hbb.IPeerInfo|null|undefined} peer_info
         * @memberof hbb.LoginResponse
         * @instance
         */
        LoginResponse.prototype.peer_info = null;

        /**
         * LoginResponse enable_trusted_devices.
         * @member {boolean} enable_trusted_devices
         * @memberof hbb.LoginResponse
         * @instance
         */
        LoginResponse.prototype.enable_trusted_devices = false;

        // OneOf field names bound to virtual getters and setters
        let $oneOfFields;

        /**
         * LoginResponse union.
         * @member {"error"|"peer_info"|undefined} union
         * @memberof hbb.LoginResponse
         * @instance
         */
        Object.defineProperty(LoginResponse.prototype, "union", {
            get: $util.oneOfGetter($oneOfFields = ["error", "peer_info"]),
            set: $util.oneOfSetter($oneOfFields)
        });

        /**
         * Creates a new LoginResponse instance using the specified properties.
         * @function create
         * @memberof hbb.LoginResponse
         * @static
         * @param {hbb.ILoginResponse=} [properties] Properties to set
         * @returns {hbb.LoginResponse} LoginResponse instance
         */
        LoginResponse.create = function create(properties) {
            return new LoginResponse(properties);
        };

        /**
         * Encodes the specified LoginResponse message. Does not implicitly {@link hbb.LoginResponse.verify|verify} messages.
         * @function encode
         * @memberof hbb.LoginResponse
         * @static
         * @param {hbb.ILoginResponse} message LoginResponse message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        LoginResponse.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.error != null && Object.hasOwnProperty.call(message, "error"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.error);
            if (message.peer_info != null && Object.hasOwnProperty.call(message, "peer_info"))
                $root.hbb.PeerInfo.encode(message.peer_info, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            if (message.enable_trusted_devices != null && Object.hasOwnProperty.call(message, "enable_trusted_devices"))
                writer.uint32(/* id 3, wireType 0 =*/24).bool(message.enable_trusted_devices);
            return writer;
        };

        /**
         * Encodes the specified LoginResponse message, length delimited. Does not implicitly {@link hbb.LoginResponse.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.LoginResponse
         * @static
         * @param {hbb.ILoginResponse} message LoginResponse message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        LoginResponse.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a LoginResponse message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.LoginResponse
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.LoginResponse} LoginResponse
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        LoginResponse.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.LoginResponse();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.error = reader.string();
                        break;
                    }
                case 2: {
                        message.peer_info = $root.hbb.PeerInfo.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 3: {
                        message.enable_trusted_devices = reader.bool();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a LoginResponse message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.LoginResponse
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.LoginResponse} LoginResponse
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        LoginResponse.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a LoginResponse message.
         * @function verify
         * @memberof hbb.LoginResponse
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        LoginResponse.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            let properties = {};
            if (message.error != null && message.hasOwnProperty("error")) {
                properties.union = 1;
                if (!$util.isString(message.error))
                    return "error: string expected";
            }
            if (message.peer_info != null && message.hasOwnProperty("peer_info")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.PeerInfo.verify(message.peer_info, long + 1);
                    if (error)
                        return "peer_info." + error;
                }
            }
            if (message.enable_trusted_devices != null && message.hasOwnProperty("enable_trusted_devices"))
                if (typeof message.enable_trusted_devices !== "boolean")
                    return "enable_trusted_devices: boolean expected";
            return null;
        };

        /**
         * Creates a LoginResponse message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.LoginResponse
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.LoginResponse} LoginResponse
         */
        LoginResponse.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.LoginResponse)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.LoginResponse();
            if (object.error != null)
                message.error = String(object.error);
            if (object.peer_info != null) {
                if (typeof object.peer_info !== "object")
                    throw TypeError(".hbb.LoginResponse.peer_info: object expected");
                message.peer_info = $root.hbb.PeerInfo.fromObject(object.peer_info, long + 1);
            }
            if (object.enable_trusted_devices != null)
                message.enable_trusted_devices = Boolean(object.enable_trusted_devices);
            return message;
        };

        /**
         * Creates a plain object from a LoginResponse message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.LoginResponse
         * @static
         * @param {hbb.LoginResponse} message LoginResponse
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        LoginResponse.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults)
                object.enable_trusted_devices = false;
            if (message.error != null && message.hasOwnProperty("error")) {
                object.error = message.error;
                if (options.oneofs)
                    object.union = "error";
            }
            if (message.peer_info != null && message.hasOwnProperty("peer_info")) {
                object.peer_info = $root.hbb.PeerInfo.toObject(message.peer_info, options);
                if (options.oneofs)
                    object.union = "peer_info";
            }
            if (message.enable_trusted_devices != null && message.hasOwnProperty("enable_trusted_devices"))
                object.enable_trusted_devices = message.enable_trusted_devices;
            return object;
        };

        /**
         * Converts this LoginResponse to JSON.
         * @function toJSON
         * @memberof hbb.LoginResponse
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        LoginResponse.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for LoginResponse
         * @function getTypeUrl
         * @memberof hbb.LoginResponse
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        LoginResponse.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.LoginResponse";
        };

        return LoginResponse;
    })();

    hbb.TouchScaleUpdate = (function() {

        /**
         * Properties of a TouchScaleUpdate.
         * @memberof hbb
         * @interface ITouchScaleUpdate
         * @property {number|null} [scale] TouchScaleUpdate scale
         */

        /**
         * Constructs a new TouchScaleUpdate.
         * @memberof hbb
         * @classdesc Represents a TouchScaleUpdate.
         * @implements ITouchScaleUpdate
         * @constructor
         * @param {hbb.ITouchScaleUpdate=} [properties] Properties to set
         */
        function TouchScaleUpdate(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * TouchScaleUpdate scale.
         * @member {number} scale
         * @memberof hbb.TouchScaleUpdate
         * @instance
         */
        TouchScaleUpdate.prototype.scale = 0;

        /**
         * Creates a new TouchScaleUpdate instance using the specified properties.
         * @function create
         * @memberof hbb.TouchScaleUpdate
         * @static
         * @param {hbb.ITouchScaleUpdate=} [properties] Properties to set
         * @returns {hbb.TouchScaleUpdate} TouchScaleUpdate instance
         */
        TouchScaleUpdate.create = function create(properties) {
            return new TouchScaleUpdate(properties);
        };

        /**
         * Encodes the specified TouchScaleUpdate message. Does not implicitly {@link hbb.TouchScaleUpdate.verify|verify} messages.
         * @function encode
         * @memberof hbb.TouchScaleUpdate
         * @static
         * @param {hbb.ITouchScaleUpdate} message TouchScaleUpdate message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        TouchScaleUpdate.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.scale != null && Object.hasOwnProperty.call(message, "scale"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.scale);
            return writer;
        };

        /**
         * Encodes the specified TouchScaleUpdate message, length delimited. Does not implicitly {@link hbb.TouchScaleUpdate.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.TouchScaleUpdate
         * @static
         * @param {hbb.ITouchScaleUpdate} message TouchScaleUpdate message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        TouchScaleUpdate.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a TouchScaleUpdate message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.TouchScaleUpdate
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.TouchScaleUpdate} TouchScaleUpdate
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        TouchScaleUpdate.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.TouchScaleUpdate();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.scale = reader.int32();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a TouchScaleUpdate message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.TouchScaleUpdate
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.TouchScaleUpdate} TouchScaleUpdate
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        TouchScaleUpdate.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a TouchScaleUpdate message.
         * @function verify
         * @memberof hbb.TouchScaleUpdate
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        TouchScaleUpdate.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.scale != null && message.hasOwnProperty("scale"))
                if (!$util.isInteger(message.scale))
                    return "scale: integer expected";
            return null;
        };

        /**
         * Creates a TouchScaleUpdate message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.TouchScaleUpdate
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.TouchScaleUpdate} TouchScaleUpdate
         */
        TouchScaleUpdate.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.TouchScaleUpdate)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.TouchScaleUpdate();
            if (object.scale != null)
                message.scale = object.scale | 0;
            return message;
        };

        /**
         * Creates a plain object from a TouchScaleUpdate message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.TouchScaleUpdate
         * @static
         * @param {hbb.TouchScaleUpdate} message TouchScaleUpdate
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        TouchScaleUpdate.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults)
                object.scale = 0;
            if (message.scale != null && message.hasOwnProperty("scale"))
                object.scale = message.scale;
            return object;
        };

        /**
         * Converts this TouchScaleUpdate to JSON.
         * @function toJSON
         * @memberof hbb.TouchScaleUpdate
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        TouchScaleUpdate.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for TouchScaleUpdate
         * @function getTypeUrl
         * @memberof hbb.TouchScaleUpdate
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        TouchScaleUpdate.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.TouchScaleUpdate";
        };

        return TouchScaleUpdate;
    })();

    hbb.TouchPanStart = (function() {

        /**
         * Properties of a TouchPanStart.
         * @memberof hbb
         * @interface ITouchPanStart
         * @property {number|null} [x] TouchPanStart x
         * @property {number|null} [y] TouchPanStart y
         */

        /**
         * Constructs a new TouchPanStart.
         * @memberof hbb
         * @classdesc Represents a TouchPanStart.
         * @implements ITouchPanStart
         * @constructor
         * @param {hbb.ITouchPanStart=} [properties] Properties to set
         */
        function TouchPanStart(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * TouchPanStart x.
         * @member {number} x
         * @memberof hbb.TouchPanStart
         * @instance
         */
        TouchPanStart.prototype.x = 0;

        /**
         * TouchPanStart y.
         * @member {number} y
         * @memberof hbb.TouchPanStart
         * @instance
         */
        TouchPanStart.prototype.y = 0;

        /**
         * Creates a new TouchPanStart instance using the specified properties.
         * @function create
         * @memberof hbb.TouchPanStart
         * @static
         * @param {hbb.ITouchPanStart=} [properties] Properties to set
         * @returns {hbb.TouchPanStart} TouchPanStart instance
         */
        TouchPanStart.create = function create(properties) {
            return new TouchPanStart(properties);
        };

        /**
         * Encodes the specified TouchPanStart message. Does not implicitly {@link hbb.TouchPanStart.verify|verify} messages.
         * @function encode
         * @memberof hbb.TouchPanStart
         * @static
         * @param {hbb.ITouchPanStart} message TouchPanStart message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        TouchPanStart.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.x != null && Object.hasOwnProperty.call(message, "x"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.x);
            if (message.y != null && Object.hasOwnProperty.call(message, "y"))
                writer.uint32(/* id 2, wireType 0 =*/16).int32(message.y);
            return writer;
        };

        /**
         * Encodes the specified TouchPanStart message, length delimited. Does not implicitly {@link hbb.TouchPanStart.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.TouchPanStart
         * @static
         * @param {hbb.ITouchPanStart} message TouchPanStart message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        TouchPanStart.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a TouchPanStart message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.TouchPanStart
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.TouchPanStart} TouchPanStart
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        TouchPanStart.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.TouchPanStart();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.x = reader.int32();
                        break;
                    }
                case 2: {
                        message.y = reader.int32();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a TouchPanStart message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.TouchPanStart
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.TouchPanStart} TouchPanStart
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        TouchPanStart.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a TouchPanStart message.
         * @function verify
         * @memberof hbb.TouchPanStart
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        TouchPanStart.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.x != null && message.hasOwnProperty("x"))
                if (!$util.isInteger(message.x))
                    return "x: integer expected";
            if (message.y != null && message.hasOwnProperty("y"))
                if (!$util.isInteger(message.y))
                    return "y: integer expected";
            return null;
        };

        /**
         * Creates a TouchPanStart message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.TouchPanStart
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.TouchPanStart} TouchPanStart
         */
        TouchPanStart.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.TouchPanStart)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.TouchPanStart();
            if (object.x != null)
                message.x = object.x | 0;
            if (object.y != null)
                message.y = object.y | 0;
            return message;
        };

        /**
         * Creates a plain object from a TouchPanStart message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.TouchPanStart
         * @static
         * @param {hbb.TouchPanStart} message TouchPanStart
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        TouchPanStart.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.x = 0;
                object.y = 0;
            }
            if (message.x != null && message.hasOwnProperty("x"))
                object.x = message.x;
            if (message.y != null && message.hasOwnProperty("y"))
                object.y = message.y;
            return object;
        };

        /**
         * Converts this TouchPanStart to JSON.
         * @function toJSON
         * @memberof hbb.TouchPanStart
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        TouchPanStart.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for TouchPanStart
         * @function getTypeUrl
         * @memberof hbb.TouchPanStart
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        TouchPanStart.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.TouchPanStart";
        };

        return TouchPanStart;
    })();

    hbb.TouchPanUpdate = (function() {

        /**
         * Properties of a TouchPanUpdate.
         * @memberof hbb
         * @interface ITouchPanUpdate
         * @property {number|null} [x] TouchPanUpdate x
         * @property {number|null} [y] TouchPanUpdate y
         */

        /**
         * Constructs a new TouchPanUpdate.
         * @memberof hbb
         * @classdesc Represents a TouchPanUpdate.
         * @implements ITouchPanUpdate
         * @constructor
         * @param {hbb.ITouchPanUpdate=} [properties] Properties to set
         */
        function TouchPanUpdate(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * TouchPanUpdate x.
         * @member {number} x
         * @memberof hbb.TouchPanUpdate
         * @instance
         */
        TouchPanUpdate.prototype.x = 0;

        /**
         * TouchPanUpdate y.
         * @member {number} y
         * @memberof hbb.TouchPanUpdate
         * @instance
         */
        TouchPanUpdate.prototype.y = 0;

        /**
         * Creates a new TouchPanUpdate instance using the specified properties.
         * @function create
         * @memberof hbb.TouchPanUpdate
         * @static
         * @param {hbb.ITouchPanUpdate=} [properties] Properties to set
         * @returns {hbb.TouchPanUpdate} TouchPanUpdate instance
         */
        TouchPanUpdate.create = function create(properties) {
            return new TouchPanUpdate(properties);
        };

        /**
         * Encodes the specified TouchPanUpdate message. Does not implicitly {@link hbb.TouchPanUpdate.verify|verify} messages.
         * @function encode
         * @memberof hbb.TouchPanUpdate
         * @static
         * @param {hbb.ITouchPanUpdate} message TouchPanUpdate message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        TouchPanUpdate.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.x != null && Object.hasOwnProperty.call(message, "x"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.x);
            if (message.y != null && Object.hasOwnProperty.call(message, "y"))
                writer.uint32(/* id 2, wireType 0 =*/16).int32(message.y);
            return writer;
        };

        /**
         * Encodes the specified TouchPanUpdate message, length delimited. Does not implicitly {@link hbb.TouchPanUpdate.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.TouchPanUpdate
         * @static
         * @param {hbb.ITouchPanUpdate} message TouchPanUpdate message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        TouchPanUpdate.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a TouchPanUpdate message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.TouchPanUpdate
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.TouchPanUpdate} TouchPanUpdate
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        TouchPanUpdate.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.TouchPanUpdate();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.x = reader.int32();
                        break;
                    }
                case 2: {
                        message.y = reader.int32();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a TouchPanUpdate message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.TouchPanUpdate
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.TouchPanUpdate} TouchPanUpdate
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        TouchPanUpdate.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a TouchPanUpdate message.
         * @function verify
         * @memberof hbb.TouchPanUpdate
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        TouchPanUpdate.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.x != null && message.hasOwnProperty("x"))
                if (!$util.isInteger(message.x))
                    return "x: integer expected";
            if (message.y != null && message.hasOwnProperty("y"))
                if (!$util.isInteger(message.y))
                    return "y: integer expected";
            return null;
        };

        /**
         * Creates a TouchPanUpdate message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.TouchPanUpdate
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.TouchPanUpdate} TouchPanUpdate
         */
        TouchPanUpdate.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.TouchPanUpdate)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.TouchPanUpdate();
            if (object.x != null)
                message.x = object.x | 0;
            if (object.y != null)
                message.y = object.y | 0;
            return message;
        };

        /**
         * Creates a plain object from a TouchPanUpdate message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.TouchPanUpdate
         * @static
         * @param {hbb.TouchPanUpdate} message TouchPanUpdate
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        TouchPanUpdate.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.x = 0;
                object.y = 0;
            }
            if (message.x != null && message.hasOwnProperty("x"))
                object.x = message.x;
            if (message.y != null && message.hasOwnProperty("y"))
                object.y = message.y;
            return object;
        };

        /**
         * Converts this TouchPanUpdate to JSON.
         * @function toJSON
         * @memberof hbb.TouchPanUpdate
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        TouchPanUpdate.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for TouchPanUpdate
         * @function getTypeUrl
         * @memberof hbb.TouchPanUpdate
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        TouchPanUpdate.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.TouchPanUpdate";
        };

        return TouchPanUpdate;
    })();

    hbb.TouchPanEnd = (function() {

        /**
         * Properties of a TouchPanEnd.
         * @memberof hbb
         * @interface ITouchPanEnd
         * @property {number|null} [x] TouchPanEnd x
         * @property {number|null} [y] TouchPanEnd y
         */

        /**
         * Constructs a new TouchPanEnd.
         * @memberof hbb
         * @classdesc Represents a TouchPanEnd.
         * @implements ITouchPanEnd
         * @constructor
         * @param {hbb.ITouchPanEnd=} [properties] Properties to set
         */
        function TouchPanEnd(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * TouchPanEnd x.
         * @member {number} x
         * @memberof hbb.TouchPanEnd
         * @instance
         */
        TouchPanEnd.prototype.x = 0;

        /**
         * TouchPanEnd y.
         * @member {number} y
         * @memberof hbb.TouchPanEnd
         * @instance
         */
        TouchPanEnd.prototype.y = 0;

        /**
         * Creates a new TouchPanEnd instance using the specified properties.
         * @function create
         * @memberof hbb.TouchPanEnd
         * @static
         * @param {hbb.ITouchPanEnd=} [properties] Properties to set
         * @returns {hbb.TouchPanEnd} TouchPanEnd instance
         */
        TouchPanEnd.create = function create(properties) {
            return new TouchPanEnd(properties);
        };

        /**
         * Encodes the specified TouchPanEnd message. Does not implicitly {@link hbb.TouchPanEnd.verify|verify} messages.
         * @function encode
         * @memberof hbb.TouchPanEnd
         * @static
         * @param {hbb.ITouchPanEnd} message TouchPanEnd message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        TouchPanEnd.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.x != null && Object.hasOwnProperty.call(message, "x"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.x);
            if (message.y != null && Object.hasOwnProperty.call(message, "y"))
                writer.uint32(/* id 2, wireType 0 =*/16).int32(message.y);
            return writer;
        };

        /**
         * Encodes the specified TouchPanEnd message, length delimited. Does not implicitly {@link hbb.TouchPanEnd.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.TouchPanEnd
         * @static
         * @param {hbb.ITouchPanEnd} message TouchPanEnd message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        TouchPanEnd.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a TouchPanEnd message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.TouchPanEnd
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.TouchPanEnd} TouchPanEnd
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        TouchPanEnd.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.TouchPanEnd();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.x = reader.int32();
                        break;
                    }
                case 2: {
                        message.y = reader.int32();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a TouchPanEnd message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.TouchPanEnd
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.TouchPanEnd} TouchPanEnd
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        TouchPanEnd.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a TouchPanEnd message.
         * @function verify
         * @memberof hbb.TouchPanEnd
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        TouchPanEnd.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.x != null && message.hasOwnProperty("x"))
                if (!$util.isInteger(message.x))
                    return "x: integer expected";
            if (message.y != null && message.hasOwnProperty("y"))
                if (!$util.isInteger(message.y))
                    return "y: integer expected";
            return null;
        };

        /**
         * Creates a TouchPanEnd message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.TouchPanEnd
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.TouchPanEnd} TouchPanEnd
         */
        TouchPanEnd.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.TouchPanEnd)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.TouchPanEnd();
            if (object.x != null)
                message.x = object.x | 0;
            if (object.y != null)
                message.y = object.y | 0;
            return message;
        };

        /**
         * Creates a plain object from a TouchPanEnd message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.TouchPanEnd
         * @static
         * @param {hbb.TouchPanEnd} message TouchPanEnd
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        TouchPanEnd.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.x = 0;
                object.y = 0;
            }
            if (message.x != null && message.hasOwnProperty("x"))
                object.x = message.x;
            if (message.y != null && message.hasOwnProperty("y"))
                object.y = message.y;
            return object;
        };

        /**
         * Converts this TouchPanEnd to JSON.
         * @function toJSON
         * @memberof hbb.TouchPanEnd
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        TouchPanEnd.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for TouchPanEnd
         * @function getTypeUrl
         * @memberof hbb.TouchPanEnd
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        TouchPanEnd.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.TouchPanEnd";
        };

        return TouchPanEnd;
    })();

    hbb.TouchEvent = (function() {

        /**
         * Properties of a TouchEvent.
         * @memberof hbb
         * @interface ITouchEvent
         * @property {hbb.ITouchScaleUpdate|null} [scale_update] TouchEvent scale_update
         * @property {hbb.ITouchPanStart|null} [pan_start] TouchEvent pan_start
         * @property {hbb.ITouchPanUpdate|null} [pan_update] TouchEvent pan_update
         * @property {hbb.ITouchPanEnd|null} [pan_end] TouchEvent pan_end
         */

        /**
         * Constructs a new TouchEvent.
         * @memberof hbb
         * @classdesc Represents a TouchEvent.
         * @implements ITouchEvent
         * @constructor
         * @param {hbb.ITouchEvent=} [properties] Properties to set
         */
        function TouchEvent(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * TouchEvent scale_update.
         * @member {hbb.ITouchScaleUpdate|null|undefined} scale_update
         * @memberof hbb.TouchEvent
         * @instance
         */
        TouchEvent.prototype.scale_update = null;

        /**
         * TouchEvent pan_start.
         * @member {hbb.ITouchPanStart|null|undefined} pan_start
         * @memberof hbb.TouchEvent
         * @instance
         */
        TouchEvent.prototype.pan_start = null;

        /**
         * TouchEvent pan_update.
         * @member {hbb.ITouchPanUpdate|null|undefined} pan_update
         * @memberof hbb.TouchEvent
         * @instance
         */
        TouchEvent.prototype.pan_update = null;

        /**
         * TouchEvent pan_end.
         * @member {hbb.ITouchPanEnd|null|undefined} pan_end
         * @memberof hbb.TouchEvent
         * @instance
         */
        TouchEvent.prototype.pan_end = null;

        // OneOf field names bound to virtual getters and setters
        let $oneOfFields;

        /**
         * TouchEvent union.
         * @member {"scale_update"|"pan_start"|"pan_update"|"pan_end"|undefined} union
         * @memberof hbb.TouchEvent
         * @instance
         */
        Object.defineProperty(TouchEvent.prototype, "union", {
            get: $util.oneOfGetter($oneOfFields = ["scale_update", "pan_start", "pan_update", "pan_end"]),
            set: $util.oneOfSetter($oneOfFields)
        });

        /**
         * Creates a new TouchEvent instance using the specified properties.
         * @function create
         * @memberof hbb.TouchEvent
         * @static
         * @param {hbb.ITouchEvent=} [properties] Properties to set
         * @returns {hbb.TouchEvent} TouchEvent instance
         */
        TouchEvent.create = function create(properties) {
            return new TouchEvent(properties);
        };

        /**
         * Encodes the specified TouchEvent message. Does not implicitly {@link hbb.TouchEvent.verify|verify} messages.
         * @function encode
         * @memberof hbb.TouchEvent
         * @static
         * @param {hbb.ITouchEvent} message TouchEvent message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        TouchEvent.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.scale_update != null && Object.hasOwnProperty.call(message, "scale_update"))
                $root.hbb.TouchScaleUpdate.encode(message.scale_update, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.pan_start != null && Object.hasOwnProperty.call(message, "pan_start"))
                $root.hbb.TouchPanStart.encode(message.pan_start, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            if (message.pan_update != null && Object.hasOwnProperty.call(message, "pan_update"))
                $root.hbb.TouchPanUpdate.encode(message.pan_update, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
            if (message.pan_end != null && Object.hasOwnProperty.call(message, "pan_end"))
                $root.hbb.TouchPanEnd.encode(message.pan_end, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified TouchEvent message, length delimited. Does not implicitly {@link hbb.TouchEvent.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.TouchEvent
         * @static
         * @param {hbb.ITouchEvent} message TouchEvent message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        TouchEvent.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a TouchEvent message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.TouchEvent
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.TouchEvent} TouchEvent
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        TouchEvent.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.TouchEvent();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.scale_update = $root.hbb.TouchScaleUpdate.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 2: {
                        message.pan_start = $root.hbb.TouchPanStart.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 3: {
                        message.pan_update = $root.hbb.TouchPanUpdate.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 4: {
                        message.pan_end = $root.hbb.TouchPanEnd.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a TouchEvent message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.TouchEvent
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.TouchEvent} TouchEvent
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        TouchEvent.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a TouchEvent message.
         * @function verify
         * @memberof hbb.TouchEvent
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        TouchEvent.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            let properties = {};
            if (message.scale_update != null && message.hasOwnProperty("scale_update")) {
                properties.union = 1;
                {
                    let error = $root.hbb.TouchScaleUpdate.verify(message.scale_update, long + 1);
                    if (error)
                        return "scale_update." + error;
                }
            }
            if (message.pan_start != null && message.hasOwnProperty("pan_start")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.TouchPanStart.verify(message.pan_start, long + 1);
                    if (error)
                        return "pan_start." + error;
                }
            }
            if (message.pan_update != null && message.hasOwnProperty("pan_update")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.TouchPanUpdate.verify(message.pan_update, long + 1);
                    if (error)
                        return "pan_update." + error;
                }
            }
            if (message.pan_end != null && message.hasOwnProperty("pan_end")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.TouchPanEnd.verify(message.pan_end, long + 1);
                    if (error)
                        return "pan_end." + error;
                }
            }
            return null;
        };

        /**
         * Creates a TouchEvent message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.TouchEvent
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.TouchEvent} TouchEvent
         */
        TouchEvent.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.TouchEvent)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.TouchEvent();
            if (object.scale_update != null) {
                if (typeof object.scale_update !== "object")
                    throw TypeError(".hbb.TouchEvent.scale_update: object expected");
                message.scale_update = $root.hbb.TouchScaleUpdate.fromObject(object.scale_update, long + 1);
            }
            if (object.pan_start != null) {
                if (typeof object.pan_start !== "object")
                    throw TypeError(".hbb.TouchEvent.pan_start: object expected");
                message.pan_start = $root.hbb.TouchPanStart.fromObject(object.pan_start, long + 1);
            }
            if (object.pan_update != null) {
                if (typeof object.pan_update !== "object")
                    throw TypeError(".hbb.TouchEvent.pan_update: object expected");
                message.pan_update = $root.hbb.TouchPanUpdate.fromObject(object.pan_update, long + 1);
            }
            if (object.pan_end != null) {
                if (typeof object.pan_end !== "object")
                    throw TypeError(".hbb.TouchEvent.pan_end: object expected");
                message.pan_end = $root.hbb.TouchPanEnd.fromObject(object.pan_end, long + 1);
            }
            return message;
        };

        /**
         * Creates a plain object from a TouchEvent message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.TouchEvent
         * @static
         * @param {hbb.TouchEvent} message TouchEvent
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        TouchEvent.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (message.scale_update != null && message.hasOwnProperty("scale_update")) {
                object.scale_update = $root.hbb.TouchScaleUpdate.toObject(message.scale_update, options);
                if (options.oneofs)
                    object.union = "scale_update";
            }
            if (message.pan_start != null && message.hasOwnProperty("pan_start")) {
                object.pan_start = $root.hbb.TouchPanStart.toObject(message.pan_start, options);
                if (options.oneofs)
                    object.union = "pan_start";
            }
            if (message.pan_update != null && message.hasOwnProperty("pan_update")) {
                object.pan_update = $root.hbb.TouchPanUpdate.toObject(message.pan_update, options);
                if (options.oneofs)
                    object.union = "pan_update";
            }
            if (message.pan_end != null && message.hasOwnProperty("pan_end")) {
                object.pan_end = $root.hbb.TouchPanEnd.toObject(message.pan_end, options);
                if (options.oneofs)
                    object.union = "pan_end";
            }
            return object;
        };

        /**
         * Converts this TouchEvent to JSON.
         * @function toJSON
         * @memberof hbb.TouchEvent
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        TouchEvent.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for TouchEvent
         * @function getTypeUrl
         * @memberof hbb.TouchEvent
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        TouchEvent.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.TouchEvent";
        };

        return TouchEvent;
    })();

    hbb.PointerDeviceEvent = (function() {

        /**
         * Properties of a PointerDeviceEvent.
         * @memberof hbb
         * @interface IPointerDeviceEvent
         * @property {hbb.ITouchEvent|null} [touch_event] PointerDeviceEvent touch_event
         * @property {Array.<hbb.ControlKey>|null} [modifiers] PointerDeviceEvent modifiers
         */

        /**
         * Constructs a new PointerDeviceEvent.
         * @memberof hbb
         * @classdesc Represents a PointerDeviceEvent.
         * @implements IPointerDeviceEvent
         * @constructor
         * @param {hbb.IPointerDeviceEvent=} [properties] Properties to set
         */
        function PointerDeviceEvent(properties) {
            this.modifiers = [];
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * PointerDeviceEvent touch_event.
         * @member {hbb.ITouchEvent|null|undefined} touch_event
         * @memberof hbb.PointerDeviceEvent
         * @instance
         */
        PointerDeviceEvent.prototype.touch_event = null;

        /**
         * PointerDeviceEvent modifiers.
         * @member {Array.<hbb.ControlKey>} modifiers
         * @memberof hbb.PointerDeviceEvent
         * @instance
         */
        PointerDeviceEvent.prototype.modifiers = $util.emptyArray;

        // OneOf field names bound to virtual getters and setters
        let $oneOfFields;

        /**
         * PointerDeviceEvent union.
         * @member {"touch_event"|undefined} union
         * @memberof hbb.PointerDeviceEvent
         * @instance
         */
        Object.defineProperty(PointerDeviceEvent.prototype, "union", {
            get: $util.oneOfGetter($oneOfFields = ["touch_event"]),
            set: $util.oneOfSetter($oneOfFields)
        });

        /**
         * Creates a new PointerDeviceEvent instance using the specified properties.
         * @function create
         * @memberof hbb.PointerDeviceEvent
         * @static
         * @param {hbb.IPointerDeviceEvent=} [properties] Properties to set
         * @returns {hbb.PointerDeviceEvent} PointerDeviceEvent instance
         */
        PointerDeviceEvent.create = function create(properties) {
            return new PointerDeviceEvent(properties);
        };

        /**
         * Encodes the specified PointerDeviceEvent message. Does not implicitly {@link hbb.PointerDeviceEvent.verify|verify} messages.
         * @function encode
         * @memberof hbb.PointerDeviceEvent
         * @static
         * @param {hbb.IPointerDeviceEvent} message PointerDeviceEvent message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        PointerDeviceEvent.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.touch_event != null && Object.hasOwnProperty.call(message, "touch_event"))
                $root.hbb.TouchEvent.encode(message.touch_event, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.modifiers != null && message.modifiers.length) {
                writer.uint32(/* id 2, wireType 2 =*/18).fork();
                for (let i = 0; i < message.modifiers.length; ++i)
                    writer.int32(message.modifiers[i]);
                writer.ldelim();
            }
            return writer;
        };

        /**
         * Encodes the specified PointerDeviceEvent message, length delimited. Does not implicitly {@link hbb.PointerDeviceEvent.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.PointerDeviceEvent
         * @static
         * @param {hbb.IPointerDeviceEvent} message PointerDeviceEvent message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        PointerDeviceEvent.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a PointerDeviceEvent message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.PointerDeviceEvent
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.PointerDeviceEvent} PointerDeviceEvent
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        PointerDeviceEvent.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.PointerDeviceEvent();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.touch_event = $root.hbb.TouchEvent.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 2: {
                        if (!(message.modifiers && message.modifiers.length))
                            message.modifiers = [];
                        if ((tag & 7) === 2) {
                            let end2 = reader.uint32() + reader.pos;
                            while (reader.pos < end2)
                                message.modifiers.push(reader.int32());
                        } else
                            message.modifiers.push(reader.int32());
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a PointerDeviceEvent message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.PointerDeviceEvent
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.PointerDeviceEvent} PointerDeviceEvent
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        PointerDeviceEvent.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a PointerDeviceEvent message.
         * @function verify
         * @memberof hbb.PointerDeviceEvent
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        PointerDeviceEvent.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            let properties = {};
            if (message.touch_event != null && message.hasOwnProperty("touch_event")) {
                properties.union = 1;
                {
                    let error = $root.hbb.TouchEvent.verify(message.touch_event, long + 1);
                    if (error)
                        return "touch_event." + error;
                }
            }
            if (message.modifiers != null && message.hasOwnProperty("modifiers")) {
                if (!Array.isArray(message.modifiers))
                    return "modifiers: array expected";
                for (let i = 0; i < message.modifiers.length; ++i)
                    switch (message.modifiers[i]) {
                    default:
                        return "modifiers: enum value[] expected";
                    case 0:
                    case 1:
                    case 2:
                    case 3:
                    case 4:
                    case 5:
                    case 6:
                    case 7:
                    case 8:
                    case 9:
                    case 10:
                    case 11:
                    case 12:
                    case 13:
                    case 14:
                    case 15:
                    case 16:
                    case 17:
                    case 18:
                    case 19:
                    case 20:
                    case 21:
                    case 22:
                    case 23:
                    case 24:
                    case 25:
                    case 26:
                    case 27:
                    case 28:
                    case 29:
                    case 30:
                    case 31:
                    case 32:
                    case 33:
                    case 34:
                    case 35:
                    case 36:
                    case 37:
                    case 38:
                    case 39:
                    case 40:
                    case 41:
                    case 42:
                    case 43:
                    case 44:
                    case 45:
                    case 46:
                    case 47:
                    case 48:
                    case 49:
                    case 50:
                    case 51:
                    case 52:
                    case 53:
                    case 54:
                    case 55:
                    case 56:
                    case 57:
                    case 58:
                    case 59:
                    case 60:
                    case 61:
                    case 62:
                    case 63:
                    case 64:
                    case 65:
                    case 66:
                    case 67:
                    case 68:
                    case 69:
                    case 70:
                    case 71:
                    case 72:
                    case 73:
                    case 74:
                    case 75:
                    case 76:
                    case 77:
                    case 78:
                    case 79:
                    case 100:
                    case 101:
                        break;
                    }
            }
            return null;
        };

        /**
         * Creates a PointerDeviceEvent message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.PointerDeviceEvent
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.PointerDeviceEvent} PointerDeviceEvent
         */
        PointerDeviceEvent.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.PointerDeviceEvent)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.PointerDeviceEvent();
            if (object.touch_event != null) {
                if (typeof object.touch_event !== "object")
                    throw TypeError(".hbb.PointerDeviceEvent.touch_event: object expected");
                message.touch_event = $root.hbb.TouchEvent.fromObject(object.touch_event, long + 1);
            }
            if (object.modifiers) {
                if (!Array.isArray(object.modifiers))
                    throw TypeError(".hbb.PointerDeviceEvent.modifiers: array expected");
                message.modifiers = [];
                for (let i = 0; i < object.modifiers.length; ++i)
                    switch (object.modifiers[i]) {
                    default:
                        if (typeof object.modifiers[i] === "number") {
                            message.modifiers[i] = object.modifiers[i];
                            break;
                        }
                    case "Unknown":
                    case 0:
                        message.modifiers[i] = 0;
                        break;
                    case "Alt":
                    case 1:
                        message.modifiers[i] = 1;
                        break;
                    case "Backspace":
                    case 2:
                        message.modifiers[i] = 2;
                        break;
                    case "CapsLock":
                    case 3:
                        message.modifiers[i] = 3;
                        break;
                    case "Control":
                    case 4:
                        message.modifiers[i] = 4;
                        break;
                    case "Delete":
                    case 5:
                        message.modifiers[i] = 5;
                        break;
                    case "DownArrow":
                    case 6:
                        message.modifiers[i] = 6;
                        break;
                    case "End":
                    case 7:
                        message.modifiers[i] = 7;
                        break;
                    case "Escape":
                    case 8:
                        message.modifiers[i] = 8;
                        break;
                    case "F1":
                    case 9:
                        message.modifiers[i] = 9;
                        break;
                    case "F10":
                    case 10:
                        message.modifiers[i] = 10;
                        break;
                    case "F11":
                    case 11:
                        message.modifiers[i] = 11;
                        break;
                    case "F12":
                    case 12:
                        message.modifiers[i] = 12;
                        break;
                    case "F2":
                    case 13:
                        message.modifiers[i] = 13;
                        break;
                    case "F3":
                    case 14:
                        message.modifiers[i] = 14;
                        break;
                    case "F4":
                    case 15:
                        message.modifiers[i] = 15;
                        break;
                    case "F5":
                    case 16:
                        message.modifiers[i] = 16;
                        break;
                    case "F6":
                    case 17:
                        message.modifiers[i] = 17;
                        break;
                    case "F7":
                    case 18:
                        message.modifiers[i] = 18;
                        break;
                    case "F8":
                    case 19:
                        message.modifiers[i] = 19;
                        break;
                    case "F9":
                    case 20:
                        message.modifiers[i] = 20;
                        break;
                    case "Home":
                    case 21:
                        message.modifiers[i] = 21;
                        break;
                    case "LeftArrow":
                    case 22:
                        message.modifiers[i] = 22;
                        break;
                    case "Meta":
                    case 23:
                        message.modifiers[i] = 23;
                        break;
                    case "Option":
                    case 24:
                        message.modifiers[i] = 24;
                        break;
                    case "PageDown":
                    case 25:
                        message.modifiers[i] = 25;
                        break;
                    case "PageUp":
                    case 26:
                        message.modifiers[i] = 26;
                        break;
                    case "Return":
                    case 27:
                        message.modifiers[i] = 27;
                        break;
                    case "RightArrow":
                    case 28:
                        message.modifiers[i] = 28;
                        break;
                    case "Shift":
                    case 29:
                        message.modifiers[i] = 29;
                        break;
                    case "Space":
                    case 30:
                        message.modifiers[i] = 30;
                        break;
                    case "Tab":
                    case 31:
                        message.modifiers[i] = 31;
                        break;
                    case "UpArrow":
                    case 32:
                        message.modifiers[i] = 32;
                        break;
                    case "Numpad0":
                    case 33:
                        message.modifiers[i] = 33;
                        break;
                    case "Numpad1":
                    case 34:
                        message.modifiers[i] = 34;
                        break;
                    case "Numpad2":
                    case 35:
                        message.modifiers[i] = 35;
                        break;
                    case "Numpad3":
                    case 36:
                        message.modifiers[i] = 36;
                        break;
                    case "Numpad4":
                    case 37:
                        message.modifiers[i] = 37;
                        break;
                    case "Numpad5":
                    case 38:
                        message.modifiers[i] = 38;
                        break;
                    case "Numpad6":
                    case 39:
                        message.modifiers[i] = 39;
                        break;
                    case "Numpad7":
                    case 40:
                        message.modifiers[i] = 40;
                        break;
                    case "Numpad8":
                    case 41:
                        message.modifiers[i] = 41;
                        break;
                    case "Numpad9":
                    case 42:
                        message.modifiers[i] = 42;
                        break;
                    case "Cancel":
                    case 43:
                        message.modifiers[i] = 43;
                        break;
                    case "Clear":
                    case 44:
                        message.modifiers[i] = 44;
                        break;
                    case "Menu":
                    case 45:
                        message.modifiers[i] = 45;
                        break;
                    case "Pause":
                    case 46:
                        message.modifiers[i] = 46;
                        break;
                    case "Kana":
                    case 47:
                        message.modifiers[i] = 47;
                        break;
                    case "Hangul":
                    case 48:
                        message.modifiers[i] = 48;
                        break;
                    case "Junja":
                    case 49:
                        message.modifiers[i] = 49;
                        break;
                    case "Final":
                    case 50:
                        message.modifiers[i] = 50;
                        break;
                    case "Hanja":
                    case 51:
                        message.modifiers[i] = 51;
                        break;
                    case "Kanji":
                    case 52:
                        message.modifiers[i] = 52;
                        break;
                    case "Convert":
                    case 53:
                        message.modifiers[i] = 53;
                        break;
                    case "Select":
                    case 54:
                        message.modifiers[i] = 54;
                        break;
                    case "Print":
                    case 55:
                        message.modifiers[i] = 55;
                        break;
                    case "Execute":
                    case 56:
                        message.modifiers[i] = 56;
                        break;
                    case "Snapshot":
                    case 57:
                        message.modifiers[i] = 57;
                        break;
                    case "Insert":
                    case 58:
                        message.modifiers[i] = 58;
                        break;
                    case "Help":
                    case 59:
                        message.modifiers[i] = 59;
                        break;
                    case "Sleep":
                    case 60:
                        message.modifiers[i] = 60;
                        break;
                    case "Separator":
                    case 61:
                        message.modifiers[i] = 61;
                        break;
                    case "Scroll":
                    case 62:
                        message.modifiers[i] = 62;
                        break;
                    case "NumLock":
                    case 63:
                        message.modifiers[i] = 63;
                        break;
                    case "RWin":
                    case 64:
                        message.modifiers[i] = 64;
                        break;
                    case "Apps":
                    case 65:
                        message.modifiers[i] = 65;
                        break;
                    case "Multiply":
                    case 66:
                        message.modifiers[i] = 66;
                        break;
                    case "Add":
                    case 67:
                        message.modifiers[i] = 67;
                        break;
                    case "Subtract":
                    case 68:
                        message.modifiers[i] = 68;
                        break;
                    case "Decimal":
                    case 69:
                        message.modifiers[i] = 69;
                        break;
                    case "Divide":
                    case 70:
                        message.modifiers[i] = 70;
                        break;
                    case "Equals":
                    case 71:
                        message.modifiers[i] = 71;
                        break;
                    case "NumpadEnter":
                    case 72:
                        message.modifiers[i] = 72;
                        break;
                    case "RShift":
                    case 73:
                        message.modifiers[i] = 73;
                        break;
                    case "RControl":
                    case 74:
                        message.modifiers[i] = 74;
                        break;
                    case "RAlt":
                    case 75:
                        message.modifiers[i] = 75;
                        break;
                    case "VolumeMute":
                    case 76:
                        message.modifiers[i] = 76;
                        break;
                    case "VolumeUp":
                    case 77:
                        message.modifiers[i] = 77;
                        break;
                    case "VolumeDown":
                    case 78:
                        message.modifiers[i] = 78;
                        break;
                    case "Power":
                    case 79:
                        message.modifiers[i] = 79;
                        break;
                    case "CtrlAltDel":
                    case 100:
                        message.modifiers[i] = 100;
                        break;
                    case "LockScreen":
                    case 101:
                        message.modifiers[i] = 101;
                        break;
                    }
            }
            return message;
        };

        /**
         * Creates a plain object from a PointerDeviceEvent message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.PointerDeviceEvent
         * @static
         * @param {hbb.PointerDeviceEvent} message PointerDeviceEvent
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        PointerDeviceEvent.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.arrays || options.defaults)
                object.modifiers = [];
            if (message.touch_event != null && message.hasOwnProperty("touch_event")) {
                object.touch_event = $root.hbb.TouchEvent.toObject(message.touch_event, options);
                if (options.oneofs)
                    object.union = "touch_event";
            }
            if (message.modifiers && message.modifiers.length) {
                object.modifiers = [];
                for (let j = 0; j < message.modifiers.length; ++j)
                    object.modifiers[j] = options.enums === String ? $root.hbb.ControlKey[message.modifiers[j]] === undefined ? message.modifiers[j] : $root.hbb.ControlKey[message.modifiers[j]] : message.modifiers[j];
            }
            return object;
        };

        /**
         * Converts this PointerDeviceEvent to JSON.
         * @function toJSON
         * @memberof hbb.PointerDeviceEvent
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        PointerDeviceEvent.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for PointerDeviceEvent
         * @function getTypeUrl
         * @memberof hbb.PointerDeviceEvent
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        PointerDeviceEvent.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.PointerDeviceEvent";
        };

        return PointerDeviceEvent;
    })();

    hbb.MouseEvent = (function() {

        /**
         * Properties of a MouseEvent.
         * @memberof hbb
         * @interface IMouseEvent
         * @property {number|null} [mask] MouseEvent mask
         * @property {number|null} [x] MouseEvent x
         * @property {number|null} [y] MouseEvent y
         * @property {Array.<hbb.ControlKey>|null} [modifiers] MouseEvent modifiers
         */

        /**
         * Constructs a new MouseEvent.
         * @memberof hbb
         * @classdesc Represents a MouseEvent.
         * @implements IMouseEvent
         * @constructor
         * @param {hbb.IMouseEvent=} [properties] Properties to set
         */
        function MouseEvent(properties) {
            this.modifiers = [];
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * MouseEvent mask.
         * @member {number} mask
         * @memberof hbb.MouseEvent
         * @instance
         */
        MouseEvent.prototype.mask = 0;

        /**
         * MouseEvent x.
         * @member {number} x
         * @memberof hbb.MouseEvent
         * @instance
         */
        MouseEvent.prototype.x = 0;

        /**
         * MouseEvent y.
         * @member {number} y
         * @memberof hbb.MouseEvent
         * @instance
         */
        MouseEvent.prototype.y = 0;

        /**
         * MouseEvent modifiers.
         * @member {Array.<hbb.ControlKey>} modifiers
         * @memberof hbb.MouseEvent
         * @instance
         */
        MouseEvent.prototype.modifiers = $util.emptyArray;

        /**
         * Creates a new MouseEvent instance using the specified properties.
         * @function create
         * @memberof hbb.MouseEvent
         * @static
         * @param {hbb.IMouseEvent=} [properties] Properties to set
         * @returns {hbb.MouseEvent} MouseEvent instance
         */
        MouseEvent.create = function create(properties) {
            return new MouseEvent(properties);
        };

        /**
         * Encodes the specified MouseEvent message. Does not implicitly {@link hbb.MouseEvent.verify|verify} messages.
         * @function encode
         * @memberof hbb.MouseEvent
         * @static
         * @param {hbb.IMouseEvent} message MouseEvent message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        MouseEvent.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.mask != null && Object.hasOwnProperty.call(message, "mask"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.mask);
            if (message.x != null && Object.hasOwnProperty.call(message, "x"))
                writer.uint32(/* id 2, wireType 0 =*/16).sint32(message.x);
            if (message.y != null && Object.hasOwnProperty.call(message, "y"))
                writer.uint32(/* id 3, wireType 0 =*/24).sint32(message.y);
            if (message.modifiers != null && message.modifiers.length) {
                writer.uint32(/* id 4, wireType 2 =*/34).fork();
                for (let i = 0; i < message.modifiers.length; ++i)
                    writer.int32(message.modifiers[i]);
                writer.ldelim();
            }
            return writer;
        };

        /**
         * Encodes the specified MouseEvent message, length delimited. Does not implicitly {@link hbb.MouseEvent.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.MouseEvent
         * @static
         * @param {hbb.IMouseEvent} message MouseEvent message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        MouseEvent.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a MouseEvent message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.MouseEvent
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.MouseEvent} MouseEvent
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        MouseEvent.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.MouseEvent();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.mask = reader.int32();
                        break;
                    }
                case 2: {
                        message.x = reader.sint32();
                        break;
                    }
                case 3: {
                        message.y = reader.sint32();
                        break;
                    }
                case 4: {
                        if (!(message.modifiers && message.modifiers.length))
                            message.modifiers = [];
                        if ((tag & 7) === 2) {
                            let end2 = reader.uint32() + reader.pos;
                            while (reader.pos < end2)
                                message.modifiers.push(reader.int32());
                        } else
                            message.modifiers.push(reader.int32());
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a MouseEvent message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.MouseEvent
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.MouseEvent} MouseEvent
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        MouseEvent.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a MouseEvent message.
         * @function verify
         * @memberof hbb.MouseEvent
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        MouseEvent.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.mask != null && message.hasOwnProperty("mask"))
                if (!$util.isInteger(message.mask))
                    return "mask: integer expected";
            if (message.x != null && message.hasOwnProperty("x"))
                if (!$util.isInteger(message.x))
                    return "x: integer expected";
            if (message.y != null && message.hasOwnProperty("y"))
                if (!$util.isInteger(message.y))
                    return "y: integer expected";
            if (message.modifiers != null && message.hasOwnProperty("modifiers")) {
                if (!Array.isArray(message.modifiers))
                    return "modifiers: array expected";
                for (let i = 0; i < message.modifiers.length; ++i)
                    switch (message.modifiers[i]) {
                    default:
                        return "modifiers: enum value[] expected";
                    case 0:
                    case 1:
                    case 2:
                    case 3:
                    case 4:
                    case 5:
                    case 6:
                    case 7:
                    case 8:
                    case 9:
                    case 10:
                    case 11:
                    case 12:
                    case 13:
                    case 14:
                    case 15:
                    case 16:
                    case 17:
                    case 18:
                    case 19:
                    case 20:
                    case 21:
                    case 22:
                    case 23:
                    case 24:
                    case 25:
                    case 26:
                    case 27:
                    case 28:
                    case 29:
                    case 30:
                    case 31:
                    case 32:
                    case 33:
                    case 34:
                    case 35:
                    case 36:
                    case 37:
                    case 38:
                    case 39:
                    case 40:
                    case 41:
                    case 42:
                    case 43:
                    case 44:
                    case 45:
                    case 46:
                    case 47:
                    case 48:
                    case 49:
                    case 50:
                    case 51:
                    case 52:
                    case 53:
                    case 54:
                    case 55:
                    case 56:
                    case 57:
                    case 58:
                    case 59:
                    case 60:
                    case 61:
                    case 62:
                    case 63:
                    case 64:
                    case 65:
                    case 66:
                    case 67:
                    case 68:
                    case 69:
                    case 70:
                    case 71:
                    case 72:
                    case 73:
                    case 74:
                    case 75:
                    case 76:
                    case 77:
                    case 78:
                    case 79:
                    case 100:
                    case 101:
                        break;
                    }
            }
            return null;
        };

        /**
         * Creates a MouseEvent message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.MouseEvent
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.MouseEvent} MouseEvent
         */
        MouseEvent.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.MouseEvent)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.MouseEvent();
            if (object.mask != null)
                message.mask = object.mask | 0;
            if (object.x != null)
                message.x = object.x | 0;
            if (object.y != null)
                message.y = object.y | 0;
            if (object.modifiers) {
                if (!Array.isArray(object.modifiers))
                    throw TypeError(".hbb.MouseEvent.modifiers: array expected");
                message.modifiers = [];
                for (let i = 0; i < object.modifiers.length; ++i)
                    switch (object.modifiers[i]) {
                    default:
                        if (typeof object.modifiers[i] === "number") {
                            message.modifiers[i] = object.modifiers[i];
                            break;
                        }
                    case "Unknown":
                    case 0:
                        message.modifiers[i] = 0;
                        break;
                    case "Alt":
                    case 1:
                        message.modifiers[i] = 1;
                        break;
                    case "Backspace":
                    case 2:
                        message.modifiers[i] = 2;
                        break;
                    case "CapsLock":
                    case 3:
                        message.modifiers[i] = 3;
                        break;
                    case "Control":
                    case 4:
                        message.modifiers[i] = 4;
                        break;
                    case "Delete":
                    case 5:
                        message.modifiers[i] = 5;
                        break;
                    case "DownArrow":
                    case 6:
                        message.modifiers[i] = 6;
                        break;
                    case "End":
                    case 7:
                        message.modifiers[i] = 7;
                        break;
                    case "Escape":
                    case 8:
                        message.modifiers[i] = 8;
                        break;
                    case "F1":
                    case 9:
                        message.modifiers[i] = 9;
                        break;
                    case "F10":
                    case 10:
                        message.modifiers[i] = 10;
                        break;
                    case "F11":
                    case 11:
                        message.modifiers[i] = 11;
                        break;
                    case "F12":
                    case 12:
                        message.modifiers[i] = 12;
                        break;
                    case "F2":
                    case 13:
                        message.modifiers[i] = 13;
                        break;
                    case "F3":
                    case 14:
                        message.modifiers[i] = 14;
                        break;
                    case "F4":
                    case 15:
                        message.modifiers[i] = 15;
                        break;
                    case "F5":
                    case 16:
                        message.modifiers[i] = 16;
                        break;
                    case "F6":
                    case 17:
                        message.modifiers[i] = 17;
                        break;
                    case "F7":
                    case 18:
                        message.modifiers[i] = 18;
                        break;
                    case "F8":
                    case 19:
                        message.modifiers[i] = 19;
                        break;
                    case "F9":
                    case 20:
                        message.modifiers[i] = 20;
                        break;
                    case "Home":
                    case 21:
                        message.modifiers[i] = 21;
                        break;
                    case "LeftArrow":
                    case 22:
                        message.modifiers[i] = 22;
                        break;
                    case "Meta":
                    case 23:
                        message.modifiers[i] = 23;
                        break;
                    case "Option":
                    case 24:
                        message.modifiers[i] = 24;
                        break;
                    case "PageDown":
                    case 25:
                        message.modifiers[i] = 25;
                        break;
                    case "PageUp":
                    case 26:
                        message.modifiers[i] = 26;
                        break;
                    case "Return":
                    case 27:
                        message.modifiers[i] = 27;
                        break;
                    case "RightArrow":
                    case 28:
                        message.modifiers[i] = 28;
                        break;
                    case "Shift":
                    case 29:
                        message.modifiers[i] = 29;
                        break;
                    case "Space":
                    case 30:
                        message.modifiers[i] = 30;
                        break;
                    case "Tab":
                    case 31:
                        message.modifiers[i] = 31;
                        break;
                    case "UpArrow":
                    case 32:
                        message.modifiers[i] = 32;
                        break;
                    case "Numpad0":
                    case 33:
                        message.modifiers[i] = 33;
                        break;
                    case "Numpad1":
                    case 34:
                        message.modifiers[i] = 34;
                        break;
                    case "Numpad2":
                    case 35:
                        message.modifiers[i] = 35;
                        break;
                    case "Numpad3":
                    case 36:
                        message.modifiers[i] = 36;
                        break;
                    case "Numpad4":
                    case 37:
                        message.modifiers[i] = 37;
                        break;
                    case "Numpad5":
                    case 38:
                        message.modifiers[i] = 38;
                        break;
                    case "Numpad6":
                    case 39:
                        message.modifiers[i] = 39;
                        break;
                    case "Numpad7":
                    case 40:
                        message.modifiers[i] = 40;
                        break;
                    case "Numpad8":
                    case 41:
                        message.modifiers[i] = 41;
                        break;
                    case "Numpad9":
                    case 42:
                        message.modifiers[i] = 42;
                        break;
                    case "Cancel":
                    case 43:
                        message.modifiers[i] = 43;
                        break;
                    case "Clear":
                    case 44:
                        message.modifiers[i] = 44;
                        break;
                    case "Menu":
                    case 45:
                        message.modifiers[i] = 45;
                        break;
                    case "Pause":
                    case 46:
                        message.modifiers[i] = 46;
                        break;
                    case "Kana":
                    case 47:
                        message.modifiers[i] = 47;
                        break;
                    case "Hangul":
                    case 48:
                        message.modifiers[i] = 48;
                        break;
                    case "Junja":
                    case 49:
                        message.modifiers[i] = 49;
                        break;
                    case "Final":
                    case 50:
                        message.modifiers[i] = 50;
                        break;
                    case "Hanja":
                    case 51:
                        message.modifiers[i] = 51;
                        break;
                    case "Kanji":
                    case 52:
                        message.modifiers[i] = 52;
                        break;
                    case "Convert":
                    case 53:
                        message.modifiers[i] = 53;
                        break;
                    case "Select":
                    case 54:
                        message.modifiers[i] = 54;
                        break;
                    case "Print":
                    case 55:
                        message.modifiers[i] = 55;
                        break;
                    case "Execute":
                    case 56:
                        message.modifiers[i] = 56;
                        break;
                    case "Snapshot":
                    case 57:
                        message.modifiers[i] = 57;
                        break;
                    case "Insert":
                    case 58:
                        message.modifiers[i] = 58;
                        break;
                    case "Help":
                    case 59:
                        message.modifiers[i] = 59;
                        break;
                    case "Sleep":
                    case 60:
                        message.modifiers[i] = 60;
                        break;
                    case "Separator":
                    case 61:
                        message.modifiers[i] = 61;
                        break;
                    case "Scroll":
                    case 62:
                        message.modifiers[i] = 62;
                        break;
                    case "NumLock":
                    case 63:
                        message.modifiers[i] = 63;
                        break;
                    case "RWin":
                    case 64:
                        message.modifiers[i] = 64;
                        break;
                    case "Apps":
                    case 65:
                        message.modifiers[i] = 65;
                        break;
                    case "Multiply":
                    case 66:
                        message.modifiers[i] = 66;
                        break;
                    case "Add":
                    case 67:
                        message.modifiers[i] = 67;
                        break;
                    case "Subtract":
                    case 68:
                        message.modifiers[i] = 68;
                        break;
                    case "Decimal":
                    case 69:
                        message.modifiers[i] = 69;
                        break;
                    case "Divide":
                    case 70:
                        message.modifiers[i] = 70;
                        break;
                    case "Equals":
                    case 71:
                        message.modifiers[i] = 71;
                        break;
                    case "NumpadEnter":
                    case 72:
                        message.modifiers[i] = 72;
                        break;
                    case "RShift":
                    case 73:
                        message.modifiers[i] = 73;
                        break;
                    case "RControl":
                    case 74:
                        message.modifiers[i] = 74;
                        break;
                    case "RAlt":
                    case 75:
                        message.modifiers[i] = 75;
                        break;
                    case "VolumeMute":
                    case 76:
                        message.modifiers[i] = 76;
                        break;
                    case "VolumeUp":
                    case 77:
                        message.modifiers[i] = 77;
                        break;
                    case "VolumeDown":
                    case 78:
                        message.modifiers[i] = 78;
                        break;
                    case "Power":
                    case 79:
                        message.modifiers[i] = 79;
                        break;
                    case "CtrlAltDel":
                    case 100:
                        message.modifiers[i] = 100;
                        break;
                    case "LockScreen":
                    case 101:
                        message.modifiers[i] = 101;
                        break;
                    }
            }
            return message;
        };

        /**
         * Creates a plain object from a MouseEvent message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.MouseEvent
         * @static
         * @param {hbb.MouseEvent} message MouseEvent
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        MouseEvent.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.arrays || options.defaults)
                object.modifiers = [];
            if (options.defaults) {
                object.mask = 0;
                object.x = 0;
                object.y = 0;
            }
            if (message.mask != null && message.hasOwnProperty("mask"))
                object.mask = message.mask;
            if (message.x != null && message.hasOwnProperty("x"))
                object.x = message.x;
            if (message.y != null && message.hasOwnProperty("y"))
                object.y = message.y;
            if (message.modifiers && message.modifiers.length) {
                object.modifiers = [];
                for (let j = 0; j < message.modifiers.length; ++j)
                    object.modifiers[j] = options.enums === String ? $root.hbb.ControlKey[message.modifiers[j]] === undefined ? message.modifiers[j] : $root.hbb.ControlKey[message.modifiers[j]] : message.modifiers[j];
            }
            return object;
        };

        /**
         * Converts this MouseEvent to JSON.
         * @function toJSON
         * @memberof hbb.MouseEvent
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        MouseEvent.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for MouseEvent
         * @function getTypeUrl
         * @memberof hbb.MouseEvent
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        MouseEvent.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.MouseEvent";
        };

        return MouseEvent;
    })();

    /**
     * KeyboardMode enum.
     * @name hbb.KeyboardMode
     * @enum {number}
     * @property {number} Legacy=0 Legacy value
     * @property {number} Map=1 Map value
     * @property {number} Translate=2 Translate value
     * @property {number} Auto=3 Auto value
     */
    hbb.KeyboardMode = (function() {
        const valuesById = {}, values = Object.create(valuesById);
        values[valuesById[0] = "Legacy"] = 0;
        values[valuesById[1] = "Map"] = 1;
        values[valuesById[2] = "Translate"] = 2;
        values[valuesById[3] = "Auto"] = 3;
        return values;
    })();

    /**
     * ControlKey enum.
     * @name hbb.ControlKey
     * @enum {number}
     * @property {number} Unknown=0 Unknown value
     * @property {number} Alt=1 Alt value
     * @property {number} Backspace=2 Backspace value
     * @property {number} CapsLock=3 CapsLock value
     * @property {number} Control=4 Control value
     * @property {number} Delete=5 Delete value
     * @property {number} DownArrow=6 DownArrow value
     * @property {number} End=7 End value
     * @property {number} Escape=8 Escape value
     * @property {number} F1=9 F1 value
     * @property {number} F10=10 F10 value
     * @property {number} F11=11 F11 value
     * @property {number} F12=12 F12 value
     * @property {number} F2=13 F2 value
     * @property {number} F3=14 F3 value
     * @property {number} F4=15 F4 value
     * @property {number} F5=16 F5 value
     * @property {number} F6=17 F6 value
     * @property {number} F7=18 F7 value
     * @property {number} F8=19 F8 value
     * @property {number} F9=20 F9 value
     * @property {number} Home=21 Home value
     * @property {number} LeftArrow=22 LeftArrow value
     * @property {number} Meta=23 meta key (also known as "windows"; "super"; and "command")
     * @property {number} Option=24 option key on macOS (alt key on Linux and Windows)
     * @property {number} PageDown=25 PageDown value
     * @property {number} PageUp=26 PageUp value
     * @property {number} Return=27 Return value
     * @property {number} RightArrow=28 RightArrow value
     * @property {number} Shift=29 Shift value
     * @property {number} Space=30 Space value
     * @property {number} Tab=31 Tab value
     * @property {number} UpArrow=32 UpArrow value
     * @property {number} Numpad0=33 Numpad0 value
     * @property {number} Numpad1=34 Numpad1 value
     * @property {number} Numpad2=35 Numpad2 value
     * @property {number} Numpad3=36 Numpad3 value
     * @property {number} Numpad4=37 Numpad4 value
     * @property {number} Numpad5=38 Numpad5 value
     * @property {number} Numpad6=39 Numpad6 value
     * @property {number} Numpad7=40 Numpad7 value
     * @property {number} Numpad8=41 Numpad8 value
     * @property {number} Numpad9=42 Numpad9 value
     * @property {number} Cancel=43 Cancel value
     * @property {number} Clear=44 Clear value
     * @property {number} Menu=45 Menu value
     * @property {number} Pause=46 Pause value
     * @property {number} Kana=47 Kana value
     * @property {number} Hangul=48 Hangul value
     * @property {number} Junja=49 Junja value
     * @property {number} Final=50 Final value
     * @property {number} Hanja=51 Hanja value
     * @property {number} Kanji=52 Kanji value
     * @property {number} Convert=53 Convert value
     * @property {number} Select=54 Select value
     * @property {number} Print=55 Print value
     * @property {number} Execute=56 Execute value
     * @property {number} Snapshot=57 Snapshot value
     * @property {number} Insert=58 Insert value
     * @property {number} Help=59 Help value
     * @property {number} Sleep=60 Sleep value
     * @property {number} Separator=61 Separator value
     * @property {number} Scroll=62 Scroll value
     * @property {number} NumLock=63 NumLock value
     * @property {number} RWin=64 RWin value
     * @property {number} Apps=65 Apps value
     * @property {number} Multiply=66 Multiply value
     * @property {number} Add=67 Add value
     * @property {number} Subtract=68 Subtract value
     * @property {number} Decimal=69 Decimal value
     * @property {number} Divide=70 Divide value
     * @property {number} Equals=71 Equals value
     * @property {number} NumpadEnter=72 NumpadEnter value
     * @property {number} RShift=73 RShift value
     * @property {number} RControl=74 RControl value
     * @property {number} RAlt=75 RAlt value
     * @property {number} VolumeMute=76 VolumeMute value
     * @property {number} VolumeUp=77 VolumeUp value
     * @property {number} VolumeDown=78 VolumeDown value
     * @property {number} Power=79 Power value
     * @property {number} CtrlAltDel=100 CtrlAltDel value
     * @property {number} LockScreen=101 LockScreen value
     */
    hbb.ControlKey = (function() {
        const valuesById = {}, values = Object.create(valuesById);
        values[valuesById[0] = "Unknown"] = 0;
        values[valuesById[1] = "Alt"] = 1;
        values[valuesById[2] = "Backspace"] = 2;
        values[valuesById[3] = "CapsLock"] = 3;
        values[valuesById[4] = "Control"] = 4;
        values[valuesById[5] = "Delete"] = 5;
        values[valuesById[6] = "DownArrow"] = 6;
        values[valuesById[7] = "End"] = 7;
        values[valuesById[8] = "Escape"] = 8;
        values[valuesById[9] = "F1"] = 9;
        values[valuesById[10] = "F10"] = 10;
        values[valuesById[11] = "F11"] = 11;
        values[valuesById[12] = "F12"] = 12;
        values[valuesById[13] = "F2"] = 13;
        values[valuesById[14] = "F3"] = 14;
        values[valuesById[15] = "F4"] = 15;
        values[valuesById[16] = "F5"] = 16;
        values[valuesById[17] = "F6"] = 17;
        values[valuesById[18] = "F7"] = 18;
        values[valuesById[19] = "F8"] = 19;
        values[valuesById[20] = "F9"] = 20;
        values[valuesById[21] = "Home"] = 21;
        values[valuesById[22] = "LeftArrow"] = 22;
        values[valuesById[23] = "Meta"] = 23;
        values[valuesById[24] = "Option"] = 24;
        values[valuesById[25] = "PageDown"] = 25;
        values[valuesById[26] = "PageUp"] = 26;
        values[valuesById[27] = "Return"] = 27;
        values[valuesById[28] = "RightArrow"] = 28;
        values[valuesById[29] = "Shift"] = 29;
        values[valuesById[30] = "Space"] = 30;
        values[valuesById[31] = "Tab"] = 31;
        values[valuesById[32] = "UpArrow"] = 32;
        values[valuesById[33] = "Numpad0"] = 33;
        values[valuesById[34] = "Numpad1"] = 34;
        values[valuesById[35] = "Numpad2"] = 35;
        values[valuesById[36] = "Numpad3"] = 36;
        values[valuesById[37] = "Numpad4"] = 37;
        values[valuesById[38] = "Numpad5"] = 38;
        values[valuesById[39] = "Numpad6"] = 39;
        values[valuesById[40] = "Numpad7"] = 40;
        values[valuesById[41] = "Numpad8"] = 41;
        values[valuesById[42] = "Numpad9"] = 42;
        values[valuesById[43] = "Cancel"] = 43;
        values[valuesById[44] = "Clear"] = 44;
        values[valuesById[45] = "Menu"] = 45;
        values[valuesById[46] = "Pause"] = 46;
        values[valuesById[47] = "Kana"] = 47;
        values[valuesById[48] = "Hangul"] = 48;
        values[valuesById[49] = "Junja"] = 49;
        values[valuesById[50] = "Final"] = 50;
        values[valuesById[51] = "Hanja"] = 51;
        values[valuesById[52] = "Kanji"] = 52;
        values[valuesById[53] = "Convert"] = 53;
        values[valuesById[54] = "Select"] = 54;
        values[valuesById[55] = "Print"] = 55;
        values[valuesById[56] = "Execute"] = 56;
        values[valuesById[57] = "Snapshot"] = 57;
        values[valuesById[58] = "Insert"] = 58;
        values[valuesById[59] = "Help"] = 59;
        values[valuesById[60] = "Sleep"] = 60;
        values[valuesById[61] = "Separator"] = 61;
        values[valuesById[62] = "Scroll"] = 62;
        values[valuesById[63] = "NumLock"] = 63;
        values[valuesById[64] = "RWin"] = 64;
        values[valuesById[65] = "Apps"] = 65;
        values[valuesById[66] = "Multiply"] = 66;
        values[valuesById[67] = "Add"] = 67;
        values[valuesById[68] = "Subtract"] = 68;
        values[valuesById[69] = "Decimal"] = 69;
        values[valuesById[70] = "Divide"] = 70;
        values[valuesById[71] = "Equals"] = 71;
        values[valuesById[72] = "NumpadEnter"] = 72;
        values[valuesById[73] = "RShift"] = 73;
        values[valuesById[74] = "RControl"] = 74;
        values[valuesById[75] = "RAlt"] = 75;
        values[valuesById[76] = "VolumeMute"] = 76;
        values[valuesById[77] = "VolumeUp"] = 77;
        values[valuesById[78] = "VolumeDown"] = 78;
        values[valuesById[79] = "Power"] = 79;
        values[valuesById[100] = "CtrlAltDel"] = 100;
        values[valuesById[101] = "LockScreen"] = 101;
        return values;
    })();

    hbb.KeyEvent = (function() {

        /**
         * Properties of a KeyEvent.
         * @memberof hbb
         * @interface IKeyEvent
         * @property {boolean|null} [down] KeyEvent down
         * @property {boolean|null} [press] KeyEvent press
         * @property {hbb.ControlKey|null} [control_key] KeyEvent control_key
         * @property {number|null} [chr] KeyEvent chr
         * @property {number|null} [unicode] KeyEvent unicode
         * @property {string|null} [seq] KeyEvent seq
         * @property {number|null} [win2win_hotkey] KeyEvent win2win_hotkey
         * @property {Array.<hbb.ControlKey>|null} [modifiers] KeyEvent modifiers
         * @property {hbb.KeyboardMode|null} [mode] KeyEvent mode
         */

        /**
         * Constructs a new KeyEvent.
         * @memberof hbb
         * @classdesc Represents a KeyEvent.
         * @implements IKeyEvent
         * @constructor
         * @param {hbb.IKeyEvent=} [properties] Properties to set
         */
        function KeyEvent(properties) {
            this.modifiers = [];
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * KeyEvent down.
         * @member {boolean} down
         * @memberof hbb.KeyEvent
         * @instance
         */
        KeyEvent.prototype.down = false;

        /**
         * KeyEvent press.
         * @member {boolean} press
         * @memberof hbb.KeyEvent
         * @instance
         */
        KeyEvent.prototype.press = false;

        /**
         * KeyEvent control_key.
         * @member {hbb.ControlKey|null|undefined} control_key
         * @memberof hbb.KeyEvent
         * @instance
         */
        KeyEvent.prototype.control_key = null;

        /**
         * KeyEvent chr.
         * @member {number|null|undefined} chr
         * @memberof hbb.KeyEvent
         * @instance
         */
        KeyEvent.prototype.chr = null;

        /**
         * KeyEvent unicode.
         * @member {number|null|undefined} unicode
         * @memberof hbb.KeyEvent
         * @instance
         */
        KeyEvent.prototype.unicode = null;

        /**
         * KeyEvent seq.
         * @member {string|null|undefined} seq
         * @memberof hbb.KeyEvent
         * @instance
         */
        KeyEvent.prototype.seq = null;

        /**
         * KeyEvent win2win_hotkey.
         * @member {number|null|undefined} win2win_hotkey
         * @memberof hbb.KeyEvent
         * @instance
         */
        KeyEvent.prototype.win2win_hotkey = null;

        /**
         * KeyEvent modifiers.
         * @member {Array.<hbb.ControlKey>} modifiers
         * @memberof hbb.KeyEvent
         * @instance
         */
        KeyEvent.prototype.modifiers = $util.emptyArray;

        /**
         * KeyEvent mode.
         * @member {hbb.KeyboardMode} mode
         * @memberof hbb.KeyEvent
         * @instance
         */
        KeyEvent.prototype.mode = 0;

        // OneOf field names bound to virtual getters and setters
        let $oneOfFields;

        /**
         * KeyEvent union.
         * @member {"control_key"|"chr"|"unicode"|"seq"|"win2win_hotkey"|undefined} union
         * @memberof hbb.KeyEvent
         * @instance
         */
        Object.defineProperty(KeyEvent.prototype, "union", {
            get: $util.oneOfGetter($oneOfFields = ["control_key", "chr", "unicode", "seq", "win2win_hotkey"]),
            set: $util.oneOfSetter($oneOfFields)
        });

        /**
         * Creates a new KeyEvent instance using the specified properties.
         * @function create
         * @memberof hbb.KeyEvent
         * @static
         * @param {hbb.IKeyEvent=} [properties] Properties to set
         * @returns {hbb.KeyEvent} KeyEvent instance
         */
        KeyEvent.create = function create(properties) {
            return new KeyEvent(properties);
        };

        /**
         * Encodes the specified KeyEvent message. Does not implicitly {@link hbb.KeyEvent.verify|verify} messages.
         * @function encode
         * @memberof hbb.KeyEvent
         * @static
         * @param {hbb.IKeyEvent} message KeyEvent message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        KeyEvent.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.down != null && Object.hasOwnProperty.call(message, "down"))
                writer.uint32(/* id 1, wireType 0 =*/8).bool(message.down);
            if (message.press != null && Object.hasOwnProperty.call(message, "press"))
                writer.uint32(/* id 2, wireType 0 =*/16).bool(message.press);
            if (message.control_key != null && Object.hasOwnProperty.call(message, "control_key"))
                writer.uint32(/* id 3, wireType 0 =*/24).int32(message.control_key);
            if (message.chr != null && Object.hasOwnProperty.call(message, "chr"))
                writer.uint32(/* id 4, wireType 0 =*/32).uint32(message.chr);
            if (message.unicode != null && Object.hasOwnProperty.call(message, "unicode"))
                writer.uint32(/* id 5, wireType 0 =*/40).uint32(message.unicode);
            if (message.seq != null && Object.hasOwnProperty.call(message, "seq"))
                writer.uint32(/* id 6, wireType 2 =*/50).string(message.seq);
            if (message.win2win_hotkey != null && Object.hasOwnProperty.call(message, "win2win_hotkey"))
                writer.uint32(/* id 7, wireType 0 =*/56).uint32(message.win2win_hotkey);
            if (message.modifiers != null && message.modifiers.length) {
                writer.uint32(/* id 8, wireType 2 =*/66).fork();
                for (let i = 0; i < message.modifiers.length; ++i)
                    writer.int32(message.modifiers[i]);
                writer.ldelim();
            }
            if (message.mode != null && Object.hasOwnProperty.call(message, "mode"))
                writer.uint32(/* id 9, wireType 0 =*/72).int32(message.mode);
            return writer;
        };

        /**
         * Encodes the specified KeyEvent message, length delimited. Does not implicitly {@link hbb.KeyEvent.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.KeyEvent
         * @static
         * @param {hbb.IKeyEvent} message KeyEvent message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        KeyEvent.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a KeyEvent message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.KeyEvent
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.KeyEvent} KeyEvent
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        KeyEvent.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.KeyEvent();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.down = reader.bool();
                        break;
                    }
                case 2: {
                        message.press = reader.bool();
                        break;
                    }
                case 3: {
                        message.control_key = reader.int32();
                        break;
                    }
                case 4: {
                        message.chr = reader.uint32();
                        break;
                    }
                case 5: {
                        message.unicode = reader.uint32();
                        break;
                    }
                case 6: {
                        message.seq = reader.string();
                        break;
                    }
                case 7: {
                        message.win2win_hotkey = reader.uint32();
                        break;
                    }
                case 8: {
                        if (!(message.modifiers && message.modifiers.length))
                            message.modifiers = [];
                        if ((tag & 7) === 2) {
                            let end2 = reader.uint32() + reader.pos;
                            while (reader.pos < end2)
                                message.modifiers.push(reader.int32());
                        } else
                            message.modifiers.push(reader.int32());
                        break;
                    }
                case 9: {
                        message.mode = reader.int32();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a KeyEvent message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.KeyEvent
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.KeyEvent} KeyEvent
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        KeyEvent.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a KeyEvent message.
         * @function verify
         * @memberof hbb.KeyEvent
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        KeyEvent.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            let properties = {};
            if (message.down != null && message.hasOwnProperty("down"))
                if (typeof message.down !== "boolean")
                    return "down: boolean expected";
            if (message.press != null && message.hasOwnProperty("press"))
                if (typeof message.press !== "boolean")
                    return "press: boolean expected";
            if (message.control_key != null && message.hasOwnProperty("control_key")) {
                properties.union = 1;
                switch (message.control_key) {
                default:
                    return "control_key: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                case 4:
                case 5:
                case 6:
                case 7:
                case 8:
                case 9:
                case 10:
                case 11:
                case 12:
                case 13:
                case 14:
                case 15:
                case 16:
                case 17:
                case 18:
                case 19:
                case 20:
                case 21:
                case 22:
                case 23:
                case 24:
                case 25:
                case 26:
                case 27:
                case 28:
                case 29:
                case 30:
                case 31:
                case 32:
                case 33:
                case 34:
                case 35:
                case 36:
                case 37:
                case 38:
                case 39:
                case 40:
                case 41:
                case 42:
                case 43:
                case 44:
                case 45:
                case 46:
                case 47:
                case 48:
                case 49:
                case 50:
                case 51:
                case 52:
                case 53:
                case 54:
                case 55:
                case 56:
                case 57:
                case 58:
                case 59:
                case 60:
                case 61:
                case 62:
                case 63:
                case 64:
                case 65:
                case 66:
                case 67:
                case 68:
                case 69:
                case 70:
                case 71:
                case 72:
                case 73:
                case 74:
                case 75:
                case 76:
                case 77:
                case 78:
                case 79:
                case 100:
                case 101:
                    break;
                }
            }
            if (message.chr != null && message.hasOwnProperty("chr")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                if (!$util.isInteger(message.chr))
                    return "chr: integer expected";
            }
            if (message.unicode != null && message.hasOwnProperty("unicode")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                if (!$util.isInteger(message.unicode))
                    return "unicode: integer expected";
            }
            if (message.seq != null && message.hasOwnProperty("seq")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                if (!$util.isString(message.seq))
                    return "seq: string expected";
            }
            if (message.win2win_hotkey != null && message.hasOwnProperty("win2win_hotkey")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                if (!$util.isInteger(message.win2win_hotkey))
                    return "win2win_hotkey: integer expected";
            }
            if (message.modifiers != null && message.hasOwnProperty("modifiers")) {
                if (!Array.isArray(message.modifiers))
                    return "modifiers: array expected";
                for (let i = 0; i < message.modifiers.length; ++i)
                    switch (message.modifiers[i]) {
                    default:
                        return "modifiers: enum value[] expected";
                    case 0:
                    case 1:
                    case 2:
                    case 3:
                    case 4:
                    case 5:
                    case 6:
                    case 7:
                    case 8:
                    case 9:
                    case 10:
                    case 11:
                    case 12:
                    case 13:
                    case 14:
                    case 15:
                    case 16:
                    case 17:
                    case 18:
                    case 19:
                    case 20:
                    case 21:
                    case 22:
                    case 23:
                    case 24:
                    case 25:
                    case 26:
                    case 27:
                    case 28:
                    case 29:
                    case 30:
                    case 31:
                    case 32:
                    case 33:
                    case 34:
                    case 35:
                    case 36:
                    case 37:
                    case 38:
                    case 39:
                    case 40:
                    case 41:
                    case 42:
                    case 43:
                    case 44:
                    case 45:
                    case 46:
                    case 47:
                    case 48:
                    case 49:
                    case 50:
                    case 51:
                    case 52:
                    case 53:
                    case 54:
                    case 55:
                    case 56:
                    case 57:
                    case 58:
                    case 59:
                    case 60:
                    case 61:
                    case 62:
                    case 63:
                    case 64:
                    case 65:
                    case 66:
                    case 67:
                    case 68:
                    case 69:
                    case 70:
                    case 71:
                    case 72:
                    case 73:
                    case 74:
                    case 75:
                    case 76:
                    case 77:
                    case 78:
                    case 79:
                    case 100:
                    case 101:
                        break;
                    }
            }
            if (message.mode != null && message.hasOwnProperty("mode"))
                switch (message.mode) {
                default:
                    return "mode: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            return null;
        };

        /**
         * Creates a KeyEvent message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.KeyEvent
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.KeyEvent} KeyEvent
         */
        KeyEvent.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.KeyEvent)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.KeyEvent();
            if (object.down != null)
                message.down = Boolean(object.down);
            if (object.press != null)
                message.press = Boolean(object.press);
            switch (object.control_key) {
            default:
                if (typeof object.control_key === "number") {
                    message.control_key = object.control_key;
                    break;
                }
                break;
            case "Unknown":
            case 0:
                message.control_key = 0;
                break;
            case "Alt":
            case 1:
                message.control_key = 1;
                break;
            case "Backspace":
            case 2:
                message.control_key = 2;
                break;
            case "CapsLock":
            case 3:
                message.control_key = 3;
                break;
            case "Control":
            case 4:
                message.control_key = 4;
                break;
            case "Delete":
            case 5:
                message.control_key = 5;
                break;
            case "DownArrow":
            case 6:
                message.control_key = 6;
                break;
            case "End":
            case 7:
                message.control_key = 7;
                break;
            case "Escape":
            case 8:
                message.control_key = 8;
                break;
            case "F1":
            case 9:
                message.control_key = 9;
                break;
            case "F10":
            case 10:
                message.control_key = 10;
                break;
            case "F11":
            case 11:
                message.control_key = 11;
                break;
            case "F12":
            case 12:
                message.control_key = 12;
                break;
            case "F2":
            case 13:
                message.control_key = 13;
                break;
            case "F3":
            case 14:
                message.control_key = 14;
                break;
            case "F4":
            case 15:
                message.control_key = 15;
                break;
            case "F5":
            case 16:
                message.control_key = 16;
                break;
            case "F6":
            case 17:
                message.control_key = 17;
                break;
            case "F7":
            case 18:
                message.control_key = 18;
                break;
            case "F8":
            case 19:
                message.control_key = 19;
                break;
            case "F9":
            case 20:
                message.control_key = 20;
                break;
            case "Home":
            case 21:
                message.control_key = 21;
                break;
            case "LeftArrow":
            case 22:
                message.control_key = 22;
                break;
            case "Meta":
            case 23:
                message.control_key = 23;
                break;
            case "Option":
            case 24:
                message.control_key = 24;
                break;
            case "PageDown":
            case 25:
                message.control_key = 25;
                break;
            case "PageUp":
            case 26:
                message.control_key = 26;
                break;
            case "Return":
            case 27:
                message.control_key = 27;
                break;
            case "RightArrow":
            case 28:
                message.control_key = 28;
                break;
            case "Shift":
            case 29:
                message.control_key = 29;
                break;
            case "Space":
            case 30:
                message.control_key = 30;
                break;
            case "Tab":
            case 31:
                message.control_key = 31;
                break;
            case "UpArrow":
            case 32:
                message.control_key = 32;
                break;
            case "Numpad0":
            case 33:
                message.control_key = 33;
                break;
            case "Numpad1":
            case 34:
                message.control_key = 34;
                break;
            case "Numpad2":
            case 35:
                message.control_key = 35;
                break;
            case "Numpad3":
            case 36:
                message.control_key = 36;
                break;
            case "Numpad4":
            case 37:
                message.control_key = 37;
                break;
            case "Numpad5":
            case 38:
                message.control_key = 38;
                break;
            case "Numpad6":
            case 39:
                message.control_key = 39;
                break;
            case "Numpad7":
            case 40:
                message.control_key = 40;
                break;
            case "Numpad8":
            case 41:
                message.control_key = 41;
                break;
            case "Numpad9":
            case 42:
                message.control_key = 42;
                break;
            case "Cancel":
            case 43:
                message.control_key = 43;
                break;
            case "Clear":
            case 44:
                message.control_key = 44;
                break;
            case "Menu":
            case 45:
                message.control_key = 45;
                break;
            case "Pause":
            case 46:
                message.control_key = 46;
                break;
            case "Kana":
            case 47:
                message.control_key = 47;
                break;
            case "Hangul":
            case 48:
                message.control_key = 48;
                break;
            case "Junja":
            case 49:
                message.control_key = 49;
                break;
            case "Final":
            case 50:
                message.control_key = 50;
                break;
            case "Hanja":
            case 51:
                message.control_key = 51;
                break;
            case "Kanji":
            case 52:
                message.control_key = 52;
                break;
            case "Convert":
            case 53:
                message.control_key = 53;
                break;
            case "Select":
            case 54:
                message.control_key = 54;
                break;
            case "Print":
            case 55:
                message.control_key = 55;
                break;
            case "Execute":
            case 56:
                message.control_key = 56;
                break;
            case "Snapshot":
            case 57:
                message.control_key = 57;
                break;
            case "Insert":
            case 58:
                message.control_key = 58;
                break;
            case "Help":
            case 59:
                message.control_key = 59;
                break;
            case "Sleep":
            case 60:
                message.control_key = 60;
                break;
            case "Separator":
            case 61:
                message.control_key = 61;
                break;
            case "Scroll":
            case 62:
                message.control_key = 62;
                break;
            case "NumLock":
            case 63:
                message.control_key = 63;
                break;
            case "RWin":
            case 64:
                message.control_key = 64;
                break;
            case "Apps":
            case 65:
                message.control_key = 65;
                break;
            case "Multiply":
            case 66:
                message.control_key = 66;
                break;
            case "Add":
            case 67:
                message.control_key = 67;
                break;
            case "Subtract":
            case 68:
                message.control_key = 68;
                break;
            case "Decimal":
            case 69:
                message.control_key = 69;
                break;
            case "Divide":
            case 70:
                message.control_key = 70;
                break;
            case "Equals":
            case 71:
                message.control_key = 71;
                break;
            case "NumpadEnter":
            case 72:
                message.control_key = 72;
                break;
            case "RShift":
            case 73:
                message.control_key = 73;
                break;
            case "RControl":
            case 74:
                message.control_key = 74;
                break;
            case "RAlt":
            case 75:
                message.control_key = 75;
                break;
            case "VolumeMute":
            case 76:
                message.control_key = 76;
                break;
            case "VolumeUp":
            case 77:
                message.control_key = 77;
                break;
            case "VolumeDown":
            case 78:
                message.control_key = 78;
                break;
            case "Power":
            case 79:
                message.control_key = 79;
                break;
            case "CtrlAltDel":
            case 100:
                message.control_key = 100;
                break;
            case "LockScreen":
            case 101:
                message.control_key = 101;
                break;
            }
            if (object.chr != null)
                message.chr = object.chr >>> 0;
            if (object.unicode != null)
                message.unicode = object.unicode >>> 0;
            if (object.seq != null)
                message.seq = String(object.seq);
            if (object.win2win_hotkey != null)
                message.win2win_hotkey = object.win2win_hotkey >>> 0;
            if (object.modifiers) {
                if (!Array.isArray(object.modifiers))
                    throw TypeError(".hbb.KeyEvent.modifiers: array expected");
                message.modifiers = [];
                for (let i = 0; i < object.modifiers.length; ++i)
                    switch (object.modifiers[i]) {
                    default:
                        if (typeof object.modifiers[i] === "number") {
                            message.modifiers[i] = object.modifiers[i];
                            break;
                        }
                    case "Unknown":
                    case 0:
                        message.modifiers[i] = 0;
                        break;
                    case "Alt":
                    case 1:
                        message.modifiers[i] = 1;
                        break;
                    case "Backspace":
                    case 2:
                        message.modifiers[i] = 2;
                        break;
                    case "CapsLock":
                    case 3:
                        message.modifiers[i] = 3;
                        break;
                    case "Control":
                    case 4:
                        message.modifiers[i] = 4;
                        break;
                    case "Delete":
                    case 5:
                        message.modifiers[i] = 5;
                        break;
                    case "DownArrow":
                    case 6:
                        message.modifiers[i] = 6;
                        break;
                    case "End":
                    case 7:
                        message.modifiers[i] = 7;
                        break;
                    case "Escape":
                    case 8:
                        message.modifiers[i] = 8;
                        break;
                    case "F1":
                    case 9:
                        message.modifiers[i] = 9;
                        break;
                    case "F10":
                    case 10:
                        message.modifiers[i] = 10;
                        break;
                    case "F11":
                    case 11:
                        message.modifiers[i] = 11;
                        break;
                    case "F12":
                    case 12:
                        message.modifiers[i] = 12;
                        break;
                    case "F2":
                    case 13:
                        message.modifiers[i] = 13;
                        break;
                    case "F3":
                    case 14:
                        message.modifiers[i] = 14;
                        break;
                    case "F4":
                    case 15:
                        message.modifiers[i] = 15;
                        break;
                    case "F5":
                    case 16:
                        message.modifiers[i] = 16;
                        break;
                    case "F6":
                    case 17:
                        message.modifiers[i] = 17;
                        break;
                    case "F7":
                    case 18:
                        message.modifiers[i] = 18;
                        break;
                    case "F8":
                    case 19:
                        message.modifiers[i] = 19;
                        break;
                    case "F9":
                    case 20:
                        message.modifiers[i] = 20;
                        break;
                    case "Home":
                    case 21:
                        message.modifiers[i] = 21;
                        break;
                    case "LeftArrow":
                    case 22:
                        message.modifiers[i] = 22;
                        break;
                    case "Meta":
                    case 23:
                        message.modifiers[i] = 23;
                        break;
                    case "Option":
                    case 24:
                        message.modifiers[i] = 24;
                        break;
                    case "PageDown":
                    case 25:
                        message.modifiers[i] = 25;
                        break;
                    case "PageUp":
                    case 26:
                        message.modifiers[i] = 26;
                        break;
                    case "Return":
                    case 27:
                        message.modifiers[i] = 27;
                        break;
                    case "RightArrow":
                    case 28:
                        message.modifiers[i] = 28;
                        break;
                    case "Shift":
                    case 29:
                        message.modifiers[i] = 29;
                        break;
                    case "Space":
                    case 30:
                        message.modifiers[i] = 30;
                        break;
                    case "Tab":
                    case 31:
                        message.modifiers[i] = 31;
                        break;
                    case "UpArrow":
                    case 32:
                        message.modifiers[i] = 32;
                        break;
                    case "Numpad0":
                    case 33:
                        message.modifiers[i] = 33;
                        break;
                    case "Numpad1":
                    case 34:
                        message.modifiers[i] = 34;
                        break;
                    case "Numpad2":
                    case 35:
                        message.modifiers[i] = 35;
                        break;
                    case "Numpad3":
                    case 36:
                        message.modifiers[i] = 36;
                        break;
                    case "Numpad4":
                    case 37:
                        message.modifiers[i] = 37;
                        break;
                    case "Numpad5":
                    case 38:
                        message.modifiers[i] = 38;
                        break;
                    case "Numpad6":
                    case 39:
                        message.modifiers[i] = 39;
                        break;
                    case "Numpad7":
                    case 40:
                        message.modifiers[i] = 40;
                        break;
                    case "Numpad8":
                    case 41:
                        message.modifiers[i] = 41;
                        break;
                    case "Numpad9":
                    case 42:
                        message.modifiers[i] = 42;
                        break;
                    case "Cancel":
                    case 43:
                        message.modifiers[i] = 43;
                        break;
                    case "Clear":
                    case 44:
                        message.modifiers[i] = 44;
                        break;
                    case "Menu":
                    case 45:
                        message.modifiers[i] = 45;
                        break;
                    case "Pause":
                    case 46:
                        message.modifiers[i] = 46;
                        break;
                    case "Kana":
                    case 47:
                        message.modifiers[i] = 47;
                        break;
                    case "Hangul":
                    case 48:
                        message.modifiers[i] = 48;
                        break;
                    case "Junja":
                    case 49:
                        message.modifiers[i] = 49;
                        break;
                    case "Final":
                    case 50:
                        message.modifiers[i] = 50;
                        break;
                    case "Hanja":
                    case 51:
                        message.modifiers[i] = 51;
                        break;
                    case "Kanji":
                    case 52:
                        message.modifiers[i] = 52;
                        break;
                    case "Convert":
                    case 53:
                        message.modifiers[i] = 53;
                        break;
                    case "Select":
                    case 54:
                        message.modifiers[i] = 54;
                        break;
                    case "Print":
                    case 55:
                        message.modifiers[i] = 55;
                        break;
                    case "Execute":
                    case 56:
                        message.modifiers[i] = 56;
                        break;
                    case "Snapshot":
                    case 57:
                        message.modifiers[i] = 57;
                        break;
                    case "Insert":
                    case 58:
                        message.modifiers[i] = 58;
                        break;
                    case "Help":
                    case 59:
                        message.modifiers[i] = 59;
                        break;
                    case "Sleep":
                    case 60:
                        message.modifiers[i] = 60;
                        break;
                    case "Separator":
                    case 61:
                        message.modifiers[i] = 61;
                        break;
                    case "Scroll":
                    case 62:
                        message.modifiers[i] = 62;
                        break;
                    case "NumLock":
                    case 63:
                        message.modifiers[i] = 63;
                        break;
                    case "RWin":
                    case 64:
                        message.modifiers[i] = 64;
                        break;
                    case "Apps":
                    case 65:
                        message.modifiers[i] = 65;
                        break;
                    case "Multiply":
                    case 66:
                        message.modifiers[i] = 66;
                        break;
                    case "Add":
                    case 67:
                        message.modifiers[i] = 67;
                        break;
                    case "Subtract":
                    case 68:
                        message.modifiers[i] = 68;
                        break;
                    case "Decimal":
                    case 69:
                        message.modifiers[i] = 69;
                        break;
                    case "Divide":
                    case 70:
                        message.modifiers[i] = 70;
                        break;
                    case "Equals":
                    case 71:
                        message.modifiers[i] = 71;
                        break;
                    case "NumpadEnter":
                    case 72:
                        message.modifiers[i] = 72;
                        break;
                    case "RShift":
                    case 73:
                        message.modifiers[i] = 73;
                        break;
                    case "RControl":
                    case 74:
                        message.modifiers[i] = 74;
                        break;
                    case "RAlt":
                    case 75:
                        message.modifiers[i] = 75;
                        break;
                    case "VolumeMute":
                    case 76:
                        message.modifiers[i] = 76;
                        break;
                    case "VolumeUp":
                    case 77:
                        message.modifiers[i] = 77;
                        break;
                    case "VolumeDown":
                    case 78:
                        message.modifiers[i] = 78;
                        break;
                    case "Power":
                    case 79:
                        message.modifiers[i] = 79;
                        break;
                    case "CtrlAltDel":
                    case 100:
                        message.modifiers[i] = 100;
                        break;
                    case "LockScreen":
                    case 101:
                        message.modifiers[i] = 101;
                        break;
                    }
            }
            switch (object.mode) {
            default:
                if (typeof object.mode === "number") {
                    message.mode = object.mode;
                    break;
                }
                break;
            case "Legacy":
            case 0:
                message.mode = 0;
                break;
            case "Map":
            case 1:
                message.mode = 1;
                break;
            case "Translate":
            case 2:
                message.mode = 2;
                break;
            case "Auto":
            case 3:
                message.mode = 3;
                break;
            }
            return message;
        };

        /**
         * Creates a plain object from a KeyEvent message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.KeyEvent
         * @static
         * @param {hbb.KeyEvent} message KeyEvent
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        KeyEvent.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.arrays || options.defaults)
                object.modifiers = [];
            if (options.defaults) {
                object.down = false;
                object.press = false;
                object.mode = options.enums === String ? "Legacy" : 0;
            }
            if (message.down != null && message.hasOwnProperty("down"))
                object.down = message.down;
            if (message.press != null && message.hasOwnProperty("press"))
                object.press = message.press;
            if (message.control_key != null && message.hasOwnProperty("control_key")) {
                object.control_key = options.enums === String ? $root.hbb.ControlKey[message.control_key] === undefined ? message.control_key : $root.hbb.ControlKey[message.control_key] : message.control_key;
                if (options.oneofs)
                    object.union = "control_key";
            }
            if (message.chr != null && message.hasOwnProperty("chr")) {
                object.chr = message.chr;
                if (options.oneofs)
                    object.union = "chr";
            }
            if (message.unicode != null && message.hasOwnProperty("unicode")) {
                object.unicode = message.unicode;
                if (options.oneofs)
                    object.union = "unicode";
            }
            if (message.seq != null && message.hasOwnProperty("seq")) {
                object.seq = message.seq;
                if (options.oneofs)
                    object.union = "seq";
            }
            if (message.win2win_hotkey != null && message.hasOwnProperty("win2win_hotkey")) {
                object.win2win_hotkey = message.win2win_hotkey;
                if (options.oneofs)
                    object.union = "win2win_hotkey";
            }
            if (message.modifiers && message.modifiers.length) {
                object.modifiers = [];
                for (let j = 0; j < message.modifiers.length; ++j)
                    object.modifiers[j] = options.enums === String ? $root.hbb.ControlKey[message.modifiers[j]] === undefined ? message.modifiers[j] : $root.hbb.ControlKey[message.modifiers[j]] : message.modifiers[j];
            }
            if (message.mode != null && message.hasOwnProperty("mode"))
                object.mode = options.enums === String ? $root.hbb.KeyboardMode[message.mode] === undefined ? message.mode : $root.hbb.KeyboardMode[message.mode] : message.mode;
            return object;
        };

        /**
         * Converts this KeyEvent to JSON.
         * @function toJSON
         * @memberof hbb.KeyEvent
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        KeyEvent.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for KeyEvent
         * @function getTypeUrl
         * @memberof hbb.KeyEvent
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        KeyEvent.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.KeyEvent";
        };

        return KeyEvent;
    })();

    hbb.CursorData = (function() {

        /**
         * Properties of a CursorData.
         * @memberof hbb
         * @interface ICursorData
         * @property {number|Long|null} [id] CursorData id
         * @property {number|null} [hotx] CursorData hotx
         * @property {number|null} [hoty] CursorData hoty
         * @property {number|null} [width] CursorData width
         * @property {number|null} [height] CursorData height
         * @property {Uint8Array|null} [colors] CursorData colors
         */

        /**
         * Constructs a new CursorData.
         * @memberof hbb
         * @classdesc Represents a CursorData.
         * @implements ICursorData
         * @constructor
         * @param {hbb.ICursorData=} [properties] Properties to set
         */
        function CursorData(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * CursorData id.
         * @member {number|Long} id
         * @memberof hbb.CursorData
         * @instance
         */
        CursorData.prototype.id = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * CursorData hotx.
         * @member {number} hotx
         * @memberof hbb.CursorData
         * @instance
         */
        CursorData.prototype.hotx = 0;

        /**
         * CursorData hoty.
         * @member {number} hoty
         * @memberof hbb.CursorData
         * @instance
         */
        CursorData.prototype.hoty = 0;

        /**
         * CursorData width.
         * @member {number} width
         * @memberof hbb.CursorData
         * @instance
         */
        CursorData.prototype.width = 0;

        /**
         * CursorData height.
         * @member {number} height
         * @memberof hbb.CursorData
         * @instance
         */
        CursorData.prototype.height = 0;

        /**
         * CursorData colors.
         * @member {Uint8Array} colors
         * @memberof hbb.CursorData
         * @instance
         */
        CursorData.prototype.colors = $util.newBuffer([]);

        /**
         * Creates a new CursorData instance using the specified properties.
         * @function create
         * @memberof hbb.CursorData
         * @static
         * @param {hbb.ICursorData=} [properties] Properties to set
         * @returns {hbb.CursorData} CursorData instance
         */
        CursorData.create = function create(properties) {
            return new CursorData(properties);
        };

        /**
         * Encodes the specified CursorData message. Does not implicitly {@link hbb.CursorData.verify|verify} messages.
         * @function encode
         * @memberof hbb.CursorData
         * @static
         * @param {hbb.ICursorData} message CursorData message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CursorData.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.id != null && Object.hasOwnProperty.call(message, "id"))
                writer.uint32(/* id 1, wireType 0 =*/8).uint64(message.id);
            if (message.hotx != null && Object.hasOwnProperty.call(message, "hotx"))
                writer.uint32(/* id 2, wireType 0 =*/16).sint32(message.hotx);
            if (message.hoty != null && Object.hasOwnProperty.call(message, "hoty"))
                writer.uint32(/* id 3, wireType 0 =*/24).sint32(message.hoty);
            if (message.width != null && Object.hasOwnProperty.call(message, "width"))
                writer.uint32(/* id 4, wireType 0 =*/32).int32(message.width);
            if (message.height != null && Object.hasOwnProperty.call(message, "height"))
                writer.uint32(/* id 5, wireType 0 =*/40).int32(message.height);
            if (message.colors != null && Object.hasOwnProperty.call(message, "colors"))
                writer.uint32(/* id 6, wireType 2 =*/50).bytes(message.colors);
            return writer;
        };

        /**
         * Encodes the specified CursorData message, length delimited. Does not implicitly {@link hbb.CursorData.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.CursorData
         * @static
         * @param {hbb.ICursorData} message CursorData message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CursorData.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a CursorData message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.CursorData
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.CursorData} CursorData
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CursorData.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.CursorData();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.id = reader.uint64();
                        break;
                    }
                case 2: {
                        message.hotx = reader.sint32();
                        break;
                    }
                case 3: {
                        message.hoty = reader.sint32();
                        break;
                    }
                case 4: {
                        message.width = reader.int32();
                        break;
                    }
                case 5: {
                        message.height = reader.int32();
                        break;
                    }
                case 6: {
                        message.colors = reader.bytes();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a CursorData message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.CursorData
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.CursorData} CursorData
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CursorData.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a CursorData message.
         * @function verify
         * @memberof hbb.CursorData
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        CursorData.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.id != null && message.hasOwnProperty("id"))
                if (!$util.isInteger(message.id) && !(message.id && $util.isInteger(message.id.low) && $util.isInteger(message.id.high)))
                    return "id: integer|Long expected";
            if (message.hotx != null && message.hasOwnProperty("hotx"))
                if (!$util.isInteger(message.hotx))
                    return "hotx: integer expected";
            if (message.hoty != null && message.hasOwnProperty("hoty"))
                if (!$util.isInteger(message.hoty))
                    return "hoty: integer expected";
            if (message.width != null && message.hasOwnProperty("width"))
                if (!$util.isInteger(message.width))
                    return "width: integer expected";
            if (message.height != null && message.hasOwnProperty("height"))
                if (!$util.isInteger(message.height))
                    return "height: integer expected";
            if (message.colors != null && message.hasOwnProperty("colors"))
                if (!(message.colors && typeof message.colors.length === "number" || $util.isString(message.colors)))
                    return "colors: buffer expected";
            return null;
        };

        /**
         * Creates a CursorData message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.CursorData
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.CursorData} CursorData
         */
        CursorData.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.CursorData)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.CursorData();
            if (object.id != null)
                if ($util.Long)
                    (message.id = $util.Long.fromValue(object.id)).unsigned = true;
                else if (typeof object.id === "string")
                    message.id = parseInt(object.id, 10);
                else if (typeof object.id === "number")
                    message.id = object.id;
                else if (typeof object.id === "object")
                    message.id = new $util.LongBits(object.id.low >>> 0, object.id.high >>> 0).toNumber(true);
            if (object.hotx != null)
                message.hotx = object.hotx | 0;
            if (object.hoty != null)
                message.hoty = object.hoty | 0;
            if (object.width != null)
                message.width = object.width | 0;
            if (object.height != null)
                message.height = object.height | 0;
            if (object.colors != null)
                if (typeof object.colors === "string")
                    $util.base64.decode(object.colors, message.colors = $util.newBuffer($util.base64.length(object.colors)), 0);
                else if (object.colors.length >= 0)
                    message.colors = object.colors;
            return message;
        };

        /**
         * Creates a plain object from a CursorData message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.CursorData
         * @static
         * @param {hbb.CursorData} message CursorData
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        CursorData.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                if ($util.Long) {
                    let long = new $util.Long(0, 0, true);
                    object.id = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.id = options.longs === String ? "0" : 0;
                object.hotx = 0;
                object.hoty = 0;
                object.width = 0;
                object.height = 0;
                if (options.bytes === String)
                    object.colors = "";
                else {
                    object.colors = [];
                    if (options.bytes !== Array)
                        object.colors = $util.newBuffer(object.colors);
                }
            }
            if (message.id != null && message.hasOwnProperty("id"))
                if (typeof message.id === "number")
                    object.id = options.longs === String ? String(message.id) : message.id;
                else
                    object.id = options.longs === String ? $util.Long.prototype.toString.call(message.id) : options.longs === Number ? new $util.LongBits(message.id.low >>> 0, message.id.high >>> 0).toNumber(true) : message.id;
            if (message.hotx != null && message.hasOwnProperty("hotx"))
                object.hotx = message.hotx;
            if (message.hoty != null && message.hasOwnProperty("hoty"))
                object.hoty = message.hoty;
            if (message.width != null && message.hasOwnProperty("width"))
                object.width = message.width;
            if (message.height != null && message.hasOwnProperty("height"))
                object.height = message.height;
            if (message.colors != null && message.hasOwnProperty("colors"))
                object.colors = options.bytes === String ? $util.base64.encode(message.colors, 0, message.colors.length) : options.bytes === Array ? Array.prototype.slice.call(message.colors) : message.colors;
            return object;
        };

        /**
         * Converts this CursorData to JSON.
         * @function toJSON
         * @memberof hbb.CursorData
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        CursorData.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for CursorData
         * @function getTypeUrl
         * @memberof hbb.CursorData
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        CursorData.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.CursorData";
        };

        return CursorData;
    })();

    hbb.CursorPosition = (function() {

        /**
         * Properties of a CursorPosition.
         * @memberof hbb
         * @interface ICursorPosition
         * @property {number|null} [x] CursorPosition x
         * @property {number|null} [y] CursorPosition y
         */

        /**
         * Constructs a new CursorPosition.
         * @memberof hbb
         * @classdesc Represents a CursorPosition.
         * @implements ICursorPosition
         * @constructor
         * @param {hbb.ICursorPosition=} [properties] Properties to set
         */
        function CursorPosition(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * CursorPosition x.
         * @member {number} x
         * @memberof hbb.CursorPosition
         * @instance
         */
        CursorPosition.prototype.x = 0;

        /**
         * CursorPosition y.
         * @member {number} y
         * @memberof hbb.CursorPosition
         * @instance
         */
        CursorPosition.prototype.y = 0;

        /**
         * Creates a new CursorPosition instance using the specified properties.
         * @function create
         * @memberof hbb.CursorPosition
         * @static
         * @param {hbb.ICursorPosition=} [properties] Properties to set
         * @returns {hbb.CursorPosition} CursorPosition instance
         */
        CursorPosition.create = function create(properties) {
            return new CursorPosition(properties);
        };

        /**
         * Encodes the specified CursorPosition message. Does not implicitly {@link hbb.CursorPosition.verify|verify} messages.
         * @function encode
         * @memberof hbb.CursorPosition
         * @static
         * @param {hbb.ICursorPosition} message CursorPosition message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CursorPosition.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.x != null && Object.hasOwnProperty.call(message, "x"))
                writer.uint32(/* id 1, wireType 0 =*/8).sint32(message.x);
            if (message.y != null && Object.hasOwnProperty.call(message, "y"))
                writer.uint32(/* id 2, wireType 0 =*/16).sint32(message.y);
            return writer;
        };

        /**
         * Encodes the specified CursorPosition message, length delimited. Does not implicitly {@link hbb.CursorPosition.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.CursorPosition
         * @static
         * @param {hbb.ICursorPosition} message CursorPosition message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CursorPosition.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a CursorPosition message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.CursorPosition
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.CursorPosition} CursorPosition
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CursorPosition.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.CursorPosition();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.x = reader.sint32();
                        break;
                    }
                case 2: {
                        message.y = reader.sint32();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a CursorPosition message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.CursorPosition
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.CursorPosition} CursorPosition
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CursorPosition.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a CursorPosition message.
         * @function verify
         * @memberof hbb.CursorPosition
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        CursorPosition.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.x != null && message.hasOwnProperty("x"))
                if (!$util.isInteger(message.x))
                    return "x: integer expected";
            if (message.y != null && message.hasOwnProperty("y"))
                if (!$util.isInteger(message.y))
                    return "y: integer expected";
            return null;
        };

        /**
         * Creates a CursorPosition message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.CursorPosition
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.CursorPosition} CursorPosition
         */
        CursorPosition.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.CursorPosition)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.CursorPosition();
            if (object.x != null)
                message.x = object.x | 0;
            if (object.y != null)
                message.y = object.y | 0;
            return message;
        };

        /**
         * Creates a plain object from a CursorPosition message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.CursorPosition
         * @static
         * @param {hbb.CursorPosition} message CursorPosition
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        CursorPosition.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.x = 0;
                object.y = 0;
            }
            if (message.x != null && message.hasOwnProperty("x"))
                object.x = message.x;
            if (message.y != null && message.hasOwnProperty("y"))
                object.y = message.y;
            return object;
        };

        /**
         * Converts this CursorPosition to JSON.
         * @function toJSON
         * @memberof hbb.CursorPosition
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        CursorPosition.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for CursorPosition
         * @function getTypeUrl
         * @memberof hbb.CursorPosition
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        CursorPosition.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.CursorPosition";
        };

        return CursorPosition;
    })();

    hbb.Hash = (function() {

        /**
         * Properties of a Hash.
         * @memberof hbb
         * @interface IHash
         * @property {string|null} [salt] Hash salt
         * @property {string|null} [challenge] Hash challenge
         */

        /**
         * Constructs a new Hash.
         * @memberof hbb
         * @classdesc Represents a Hash.
         * @implements IHash
         * @constructor
         * @param {hbb.IHash=} [properties] Properties to set
         */
        function Hash(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * Hash salt.
         * @member {string} salt
         * @memberof hbb.Hash
         * @instance
         */
        Hash.prototype.salt = "";

        /**
         * Hash challenge.
         * @member {string} challenge
         * @memberof hbb.Hash
         * @instance
         */
        Hash.prototype.challenge = "";

        /**
         * Creates a new Hash instance using the specified properties.
         * @function create
         * @memberof hbb.Hash
         * @static
         * @param {hbb.IHash=} [properties] Properties to set
         * @returns {hbb.Hash} Hash instance
         */
        Hash.create = function create(properties) {
            return new Hash(properties);
        };

        /**
         * Encodes the specified Hash message. Does not implicitly {@link hbb.Hash.verify|verify} messages.
         * @function encode
         * @memberof hbb.Hash
         * @static
         * @param {hbb.IHash} message Hash message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Hash.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.salt != null && Object.hasOwnProperty.call(message, "salt"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.salt);
            if (message.challenge != null && Object.hasOwnProperty.call(message, "challenge"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.challenge);
            return writer;
        };

        /**
         * Encodes the specified Hash message, length delimited. Does not implicitly {@link hbb.Hash.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.Hash
         * @static
         * @param {hbb.IHash} message Hash message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Hash.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a Hash message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.Hash
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.Hash} Hash
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Hash.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.Hash();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.salt = reader.string();
                        break;
                    }
                case 2: {
                        message.challenge = reader.string();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a Hash message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.Hash
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.Hash} Hash
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Hash.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a Hash message.
         * @function verify
         * @memberof hbb.Hash
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        Hash.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.salt != null && message.hasOwnProperty("salt"))
                if (!$util.isString(message.salt))
                    return "salt: string expected";
            if (message.challenge != null && message.hasOwnProperty("challenge"))
                if (!$util.isString(message.challenge))
                    return "challenge: string expected";
            return null;
        };

        /**
         * Creates a Hash message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.Hash
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.Hash} Hash
         */
        Hash.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.Hash)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.Hash();
            if (object.salt != null)
                message.salt = String(object.salt);
            if (object.challenge != null)
                message.challenge = String(object.challenge);
            return message;
        };

        /**
         * Creates a plain object from a Hash message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.Hash
         * @static
         * @param {hbb.Hash} message Hash
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        Hash.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.salt = "";
                object.challenge = "";
            }
            if (message.salt != null && message.hasOwnProperty("salt"))
                object.salt = message.salt;
            if (message.challenge != null && message.hasOwnProperty("challenge"))
                object.challenge = message.challenge;
            return object;
        };

        /**
         * Converts this Hash to JSON.
         * @function toJSON
         * @memberof hbb.Hash
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        Hash.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for Hash
         * @function getTypeUrl
         * @memberof hbb.Hash
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        Hash.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.Hash";
        };

        return Hash;
    })();

    /**
     * ClipboardFormat enum.
     * @name hbb.ClipboardFormat
     * @enum {number}
     * @property {number} Text=0 Text value
     * @property {number} Rtf=1 Rtf value
     * @property {number} Html=2 Html value
     * @property {number} ImageRgba=21 ImageRgba value
     * @property {number} ImagePng=22 ImagePng value
     * @property {number} ImageSvg=23 ImageSvg value
     * @property {number} Special=31 Special value
     */
    hbb.ClipboardFormat = (function() {
        const valuesById = {}, values = Object.create(valuesById);
        values[valuesById[0] = "Text"] = 0;
        values[valuesById[1] = "Rtf"] = 1;
        values[valuesById[2] = "Html"] = 2;
        values[valuesById[21] = "ImageRgba"] = 21;
        values[valuesById[22] = "ImagePng"] = 22;
        values[valuesById[23] = "ImageSvg"] = 23;
        values[valuesById[31] = "Special"] = 31;
        return values;
    })();

    hbb.Clipboard = (function() {

        /**
         * Properties of a Clipboard.
         * @memberof hbb
         * @interface IClipboard
         * @property {boolean|null} [compress] Clipboard compress
         * @property {Uint8Array|null} [content] Clipboard content
         * @property {number|null} [width] Clipboard width
         * @property {number|null} [height] Clipboard height
         * @property {hbb.ClipboardFormat|null} [format] Clipboard format
         * @property {string|null} [special_name] Clipboard special_name
         */

        /**
         * Constructs a new Clipboard.
         * @memberof hbb
         * @classdesc Represents a Clipboard.
         * @implements IClipboard
         * @constructor
         * @param {hbb.IClipboard=} [properties] Properties to set
         */
        function Clipboard(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * Clipboard compress.
         * @member {boolean} compress
         * @memberof hbb.Clipboard
         * @instance
         */
        Clipboard.prototype.compress = false;

        /**
         * Clipboard content.
         * @member {Uint8Array} content
         * @memberof hbb.Clipboard
         * @instance
         */
        Clipboard.prototype.content = $util.newBuffer([]);

        /**
         * Clipboard width.
         * @member {number} width
         * @memberof hbb.Clipboard
         * @instance
         */
        Clipboard.prototype.width = 0;

        /**
         * Clipboard height.
         * @member {number} height
         * @memberof hbb.Clipboard
         * @instance
         */
        Clipboard.prototype.height = 0;

        /**
         * Clipboard format.
         * @member {hbb.ClipboardFormat} format
         * @memberof hbb.Clipboard
         * @instance
         */
        Clipboard.prototype.format = 0;

        /**
         * Clipboard special_name.
         * @member {string} special_name
         * @memberof hbb.Clipboard
         * @instance
         */
        Clipboard.prototype.special_name = "";

        /**
         * Creates a new Clipboard instance using the specified properties.
         * @function create
         * @memberof hbb.Clipboard
         * @static
         * @param {hbb.IClipboard=} [properties] Properties to set
         * @returns {hbb.Clipboard} Clipboard instance
         */
        Clipboard.create = function create(properties) {
            return new Clipboard(properties);
        };

        /**
         * Encodes the specified Clipboard message. Does not implicitly {@link hbb.Clipboard.verify|verify} messages.
         * @function encode
         * @memberof hbb.Clipboard
         * @static
         * @param {hbb.IClipboard} message Clipboard message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Clipboard.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.compress != null && Object.hasOwnProperty.call(message, "compress"))
                writer.uint32(/* id 1, wireType 0 =*/8).bool(message.compress);
            if (message.content != null && Object.hasOwnProperty.call(message, "content"))
                writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.content);
            if (message.width != null && Object.hasOwnProperty.call(message, "width"))
                writer.uint32(/* id 3, wireType 0 =*/24).int32(message.width);
            if (message.height != null && Object.hasOwnProperty.call(message, "height"))
                writer.uint32(/* id 4, wireType 0 =*/32).int32(message.height);
            if (message.format != null && Object.hasOwnProperty.call(message, "format"))
                writer.uint32(/* id 5, wireType 0 =*/40).int32(message.format);
            if (message.special_name != null && Object.hasOwnProperty.call(message, "special_name"))
                writer.uint32(/* id 6, wireType 2 =*/50).string(message.special_name);
            return writer;
        };

        /**
         * Encodes the specified Clipboard message, length delimited. Does not implicitly {@link hbb.Clipboard.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.Clipboard
         * @static
         * @param {hbb.IClipboard} message Clipboard message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Clipboard.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a Clipboard message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.Clipboard
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.Clipboard} Clipboard
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Clipboard.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.Clipboard();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.compress = reader.bool();
                        break;
                    }
                case 2: {
                        message.content = reader.bytes();
                        break;
                    }
                case 3: {
                        message.width = reader.int32();
                        break;
                    }
                case 4: {
                        message.height = reader.int32();
                        break;
                    }
                case 5: {
                        message.format = reader.int32();
                        break;
                    }
                case 6: {
                        message.special_name = reader.string();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a Clipboard message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.Clipboard
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.Clipboard} Clipboard
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Clipboard.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a Clipboard message.
         * @function verify
         * @memberof hbb.Clipboard
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        Clipboard.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.compress != null && message.hasOwnProperty("compress"))
                if (typeof message.compress !== "boolean")
                    return "compress: boolean expected";
            if (message.content != null && message.hasOwnProperty("content"))
                if (!(message.content && typeof message.content.length === "number" || $util.isString(message.content)))
                    return "content: buffer expected";
            if (message.width != null && message.hasOwnProperty("width"))
                if (!$util.isInteger(message.width))
                    return "width: integer expected";
            if (message.height != null && message.hasOwnProperty("height"))
                if (!$util.isInteger(message.height))
                    return "height: integer expected";
            if (message.format != null && message.hasOwnProperty("format"))
                switch (message.format) {
                default:
                    return "format: enum value expected";
                case 0:
                case 1:
                case 2:
                case 21:
                case 22:
                case 23:
                case 31:
                    break;
                }
            if (message.special_name != null && message.hasOwnProperty("special_name"))
                if (!$util.isString(message.special_name))
                    return "special_name: string expected";
            return null;
        };

        /**
         * Creates a Clipboard message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.Clipboard
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.Clipboard} Clipboard
         */
        Clipboard.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.Clipboard)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.Clipboard();
            if (object.compress != null)
                message.compress = Boolean(object.compress);
            if (object.content != null)
                if (typeof object.content === "string")
                    $util.base64.decode(object.content, message.content = $util.newBuffer($util.base64.length(object.content)), 0);
                else if (object.content.length >= 0)
                    message.content = object.content;
            if (object.width != null)
                message.width = object.width | 0;
            if (object.height != null)
                message.height = object.height | 0;
            switch (object.format) {
            default:
                if (typeof object.format === "number") {
                    message.format = object.format;
                    break;
                }
                break;
            case "Text":
            case 0:
                message.format = 0;
                break;
            case "Rtf":
            case 1:
                message.format = 1;
                break;
            case "Html":
            case 2:
                message.format = 2;
                break;
            case "ImageRgba":
            case 21:
                message.format = 21;
                break;
            case "ImagePng":
            case 22:
                message.format = 22;
                break;
            case "ImageSvg":
            case 23:
                message.format = 23;
                break;
            case "Special":
            case 31:
                message.format = 31;
                break;
            }
            if (object.special_name != null)
                message.special_name = String(object.special_name);
            return message;
        };

        /**
         * Creates a plain object from a Clipboard message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.Clipboard
         * @static
         * @param {hbb.Clipboard} message Clipboard
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        Clipboard.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.compress = false;
                if (options.bytes === String)
                    object.content = "";
                else {
                    object.content = [];
                    if (options.bytes !== Array)
                        object.content = $util.newBuffer(object.content);
                }
                object.width = 0;
                object.height = 0;
                object.format = options.enums === String ? "Text" : 0;
                object.special_name = "";
            }
            if (message.compress != null && message.hasOwnProperty("compress"))
                object.compress = message.compress;
            if (message.content != null && message.hasOwnProperty("content"))
                object.content = options.bytes === String ? $util.base64.encode(message.content, 0, message.content.length) : options.bytes === Array ? Array.prototype.slice.call(message.content) : message.content;
            if (message.width != null && message.hasOwnProperty("width"))
                object.width = message.width;
            if (message.height != null && message.hasOwnProperty("height"))
                object.height = message.height;
            if (message.format != null && message.hasOwnProperty("format"))
                object.format = options.enums === String ? $root.hbb.ClipboardFormat[message.format] === undefined ? message.format : $root.hbb.ClipboardFormat[message.format] : message.format;
            if (message.special_name != null && message.hasOwnProperty("special_name"))
                object.special_name = message.special_name;
            return object;
        };

        /**
         * Converts this Clipboard to JSON.
         * @function toJSON
         * @memberof hbb.Clipboard
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        Clipboard.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for Clipboard
         * @function getTypeUrl
         * @memberof hbb.Clipboard
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        Clipboard.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.Clipboard";
        };

        return Clipboard;
    })();

    hbb.MultiClipboards = (function() {

        /**
         * Properties of a MultiClipboards.
         * @memberof hbb
         * @interface IMultiClipboards
         * @property {Array.<hbb.IClipboard>|null} [clipboards] MultiClipboards clipboards
         */

        /**
         * Constructs a new MultiClipboards.
         * @memberof hbb
         * @classdesc Represents a MultiClipboards.
         * @implements IMultiClipboards
         * @constructor
         * @param {hbb.IMultiClipboards=} [properties] Properties to set
         */
        function MultiClipboards(properties) {
            this.clipboards = [];
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * MultiClipboards clipboards.
         * @member {Array.<hbb.IClipboard>} clipboards
         * @memberof hbb.MultiClipboards
         * @instance
         */
        MultiClipboards.prototype.clipboards = $util.emptyArray;

        /**
         * Creates a new MultiClipboards instance using the specified properties.
         * @function create
         * @memberof hbb.MultiClipboards
         * @static
         * @param {hbb.IMultiClipboards=} [properties] Properties to set
         * @returns {hbb.MultiClipboards} MultiClipboards instance
         */
        MultiClipboards.create = function create(properties) {
            return new MultiClipboards(properties);
        };

        /**
         * Encodes the specified MultiClipboards message. Does not implicitly {@link hbb.MultiClipboards.verify|verify} messages.
         * @function encode
         * @memberof hbb.MultiClipboards
         * @static
         * @param {hbb.IMultiClipboards} message MultiClipboards message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        MultiClipboards.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.clipboards != null && message.clipboards.length)
                for (let i = 0; i < message.clipboards.length; ++i)
                    $root.hbb.Clipboard.encode(message.clipboards[i], writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified MultiClipboards message, length delimited. Does not implicitly {@link hbb.MultiClipboards.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.MultiClipboards
         * @static
         * @param {hbb.IMultiClipboards} message MultiClipboards message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        MultiClipboards.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a MultiClipboards message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.MultiClipboards
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.MultiClipboards} MultiClipboards
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        MultiClipboards.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.MultiClipboards();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        if (!(message.clipboards && message.clipboards.length))
                            message.clipboards = [];
                        message.clipboards.push($root.hbb.Clipboard.decode(reader, reader.uint32(), undefined, long + 1));
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a MultiClipboards message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.MultiClipboards
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.MultiClipboards} MultiClipboards
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        MultiClipboards.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a MultiClipboards message.
         * @function verify
         * @memberof hbb.MultiClipboards
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        MultiClipboards.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.clipboards != null && message.hasOwnProperty("clipboards")) {
                if (!Array.isArray(message.clipboards))
                    return "clipboards: array expected";
                for (let i = 0; i < message.clipboards.length; ++i) {
                    let error = $root.hbb.Clipboard.verify(message.clipboards[i], long + 1);
                    if (error)
                        return "clipboards." + error;
                }
            }
            return null;
        };

        /**
         * Creates a MultiClipboards message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.MultiClipboards
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.MultiClipboards} MultiClipboards
         */
        MultiClipboards.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.MultiClipboards)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.MultiClipboards();
            if (object.clipboards) {
                if (!Array.isArray(object.clipboards))
                    throw TypeError(".hbb.MultiClipboards.clipboards: array expected");
                message.clipboards = [];
                for (let i = 0; i < object.clipboards.length; ++i) {
                    if (typeof object.clipboards[i] !== "object")
                        throw TypeError(".hbb.MultiClipboards.clipboards: object expected");
                    message.clipboards[i] = $root.hbb.Clipboard.fromObject(object.clipboards[i], long + 1);
                }
            }
            return message;
        };

        /**
         * Creates a plain object from a MultiClipboards message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.MultiClipboards
         * @static
         * @param {hbb.MultiClipboards} message MultiClipboards
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        MultiClipboards.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.arrays || options.defaults)
                object.clipboards = [];
            if (message.clipboards && message.clipboards.length) {
                object.clipboards = [];
                for (let j = 0; j < message.clipboards.length; ++j)
                    object.clipboards[j] = $root.hbb.Clipboard.toObject(message.clipboards[j], options);
            }
            return object;
        };

        /**
         * Converts this MultiClipboards to JSON.
         * @function toJSON
         * @memberof hbb.MultiClipboards
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        MultiClipboards.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for MultiClipboards
         * @function getTypeUrl
         * @memberof hbb.MultiClipboards
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        MultiClipboards.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.MultiClipboards";
        };

        return MultiClipboards;
    })();

    /**
     * FileType enum.
     * @name hbb.FileType
     * @enum {number}
     * @property {number} Dir=0 Dir value
     * @property {number} DirLink=2 DirLink value
     * @property {number} DirDrive=3 DirDrive value
     * @property {number} File=4 File value
     * @property {number} FileLink=5 FileLink value
     */
    hbb.FileType = (function() {
        const valuesById = {}, values = Object.create(valuesById);
        values[valuesById[0] = "Dir"] = 0;
        values[valuesById[2] = "DirLink"] = 2;
        values[valuesById[3] = "DirDrive"] = 3;
        values[valuesById[4] = "File"] = 4;
        values[valuesById[5] = "FileLink"] = 5;
        return values;
    })();

    hbb.FileEntry = (function() {

        /**
         * Properties of a FileEntry.
         * @memberof hbb
         * @interface IFileEntry
         * @property {hbb.FileType|null} [entry_type] FileEntry entry_type
         * @property {string|null} [name] FileEntry name
         * @property {boolean|null} [is_hidden] FileEntry is_hidden
         * @property {number|Long|null} [size] FileEntry size
         * @property {number|Long|null} [modified_time] FileEntry modified_time
         */

        /**
         * Constructs a new FileEntry.
         * @memberof hbb
         * @classdesc Represents a FileEntry.
         * @implements IFileEntry
         * @constructor
         * @param {hbb.IFileEntry=} [properties] Properties to set
         */
        function FileEntry(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * FileEntry entry_type.
         * @member {hbb.FileType} entry_type
         * @memberof hbb.FileEntry
         * @instance
         */
        FileEntry.prototype.entry_type = 0;

        /**
         * FileEntry name.
         * @member {string} name
         * @memberof hbb.FileEntry
         * @instance
         */
        FileEntry.prototype.name = "";

        /**
         * FileEntry is_hidden.
         * @member {boolean} is_hidden
         * @memberof hbb.FileEntry
         * @instance
         */
        FileEntry.prototype.is_hidden = false;

        /**
         * FileEntry size.
         * @member {number|Long} size
         * @memberof hbb.FileEntry
         * @instance
         */
        FileEntry.prototype.size = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * FileEntry modified_time.
         * @member {number|Long} modified_time
         * @memberof hbb.FileEntry
         * @instance
         */
        FileEntry.prototype.modified_time = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * Creates a new FileEntry instance using the specified properties.
         * @function create
         * @memberof hbb.FileEntry
         * @static
         * @param {hbb.IFileEntry=} [properties] Properties to set
         * @returns {hbb.FileEntry} FileEntry instance
         */
        FileEntry.create = function create(properties) {
            return new FileEntry(properties);
        };

        /**
         * Encodes the specified FileEntry message. Does not implicitly {@link hbb.FileEntry.verify|verify} messages.
         * @function encode
         * @memberof hbb.FileEntry
         * @static
         * @param {hbb.IFileEntry} message FileEntry message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FileEntry.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.entry_type != null && Object.hasOwnProperty.call(message, "entry_type"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.entry_type);
            if (message.name != null && Object.hasOwnProperty.call(message, "name"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.name);
            if (message.is_hidden != null && Object.hasOwnProperty.call(message, "is_hidden"))
                writer.uint32(/* id 3, wireType 0 =*/24).bool(message.is_hidden);
            if (message.size != null && Object.hasOwnProperty.call(message, "size"))
                writer.uint32(/* id 4, wireType 0 =*/32).uint64(message.size);
            if (message.modified_time != null && Object.hasOwnProperty.call(message, "modified_time"))
                writer.uint32(/* id 5, wireType 0 =*/40).uint64(message.modified_time);
            return writer;
        };

        /**
         * Encodes the specified FileEntry message, length delimited. Does not implicitly {@link hbb.FileEntry.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.FileEntry
         * @static
         * @param {hbb.IFileEntry} message FileEntry message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FileEntry.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a FileEntry message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.FileEntry
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.FileEntry} FileEntry
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FileEntry.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.FileEntry();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.entry_type = reader.int32();
                        break;
                    }
                case 2: {
                        message.name = reader.string();
                        break;
                    }
                case 3: {
                        message.is_hidden = reader.bool();
                        break;
                    }
                case 4: {
                        message.size = reader.uint64();
                        break;
                    }
                case 5: {
                        message.modified_time = reader.uint64();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a FileEntry message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.FileEntry
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.FileEntry} FileEntry
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FileEntry.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a FileEntry message.
         * @function verify
         * @memberof hbb.FileEntry
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        FileEntry.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.entry_type != null && message.hasOwnProperty("entry_type"))
                switch (message.entry_type) {
                default:
                    return "entry_type: enum value expected";
                case 0:
                case 2:
                case 3:
                case 4:
                case 5:
                    break;
                }
            if (message.name != null && message.hasOwnProperty("name"))
                if (!$util.isString(message.name))
                    return "name: string expected";
            if (message.is_hidden != null && message.hasOwnProperty("is_hidden"))
                if (typeof message.is_hidden !== "boolean")
                    return "is_hidden: boolean expected";
            if (message.size != null && message.hasOwnProperty("size"))
                if (!$util.isInteger(message.size) && !(message.size && $util.isInteger(message.size.low) && $util.isInteger(message.size.high)))
                    return "size: integer|Long expected";
            if (message.modified_time != null && message.hasOwnProperty("modified_time"))
                if (!$util.isInteger(message.modified_time) && !(message.modified_time && $util.isInteger(message.modified_time.low) && $util.isInteger(message.modified_time.high)))
                    return "modified_time: integer|Long expected";
            return null;
        };

        /**
         * Creates a FileEntry message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.FileEntry
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.FileEntry} FileEntry
         */
        FileEntry.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.FileEntry)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.FileEntry();
            switch (object.entry_type) {
            default:
                if (typeof object.entry_type === "number") {
                    message.entry_type = object.entry_type;
                    break;
                }
                break;
            case "Dir":
            case 0:
                message.entry_type = 0;
                break;
            case "DirLink":
            case 2:
                message.entry_type = 2;
                break;
            case "DirDrive":
            case 3:
                message.entry_type = 3;
                break;
            case "File":
            case 4:
                message.entry_type = 4;
                break;
            case "FileLink":
            case 5:
                message.entry_type = 5;
                break;
            }
            if (object.name != null)
                message.name = String(object.name);
            if (object.is_hidden != null)
                message.is_hidden = Boolean(object.is_hidden);
            if (object.size != null)
                if ($util.Long)
                    (message.size = $util.Long.fromValue(object.size)).unsigned = true;
                else if (typeof object.size === "string")
                    message.size = parseInt(object.size, 10);
                else if (typeof object.size === "number")
                    message.size = object.size;
                else if (typeof object.size === "object")
                    message.size = new $util.LongBits(object.size.low >>> 0, object.size.high >>> 0).toNumber(true);
            if (object.modified_time != null)
                if ($util.Long)
                    (message.modified_time = $util.Long.fromValue(object.modified_time)).unsigned = true;
                else if (typeof object.modified_time === "string")
                    message.modified_time = parseInt(object.modified_time, 10);
                else if (typeof object.modified_time === "number")
                    message.modified_time = object.modified_time;
                else if (typeof object.modified_time === "object")
                    message.modified_time = new $util.LongBits(object.modified_time.low >>> 0, object.modified_time.high >>> 0).toNumber(true);
            return message;
        };

        /**
         * Creates a plain object from a FileEntry message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.FileEntry
         * @static
         * @param {hbb.FileEntry} message FileEntry
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        FileEntry.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.entry_type = options.enums === String ? "Dir" : 0;
                object.name = "";
                object.is_hidden = false;
                if ($util.Long) {
                    let long = new $util.Long(0, 0, true);
                    object.size = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.size = options.longs === String ? "0" : 0;
                if ($util.Long) {
                    let long = new $util.Long(0, 0, true);
                    object.modified_time = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.modified_time = options.longs === String ? "0" : 0;
            }
            if (message.entry_type != null && message.hasOwnProperty("entry_type"))
                object.entry_type = options.enums === String ? $root.hbb.FileType[message.entry_type] === undefined ? message.entry_type : $root.hbb.FileType[message.entry_type] : message.entry_type;
            if (message.name != null && message.hasOwnProperty("name"))
                object.name = message.name;
            if (message.is_hidden != null && message.hasOwnProperty("is_hidden"))
                object.is_hidden = message.is_hidden;
            if (message.size != null && message.hasOwnProperty("size"))
                if (typeof message.size === "number")
                    object.size = options.longs === String ? String(message.size) : message.size;
                else
                    object.size = options.longs === String ? $util.Long.prototype.toString.call(message.size) : options.longs === Number ? new $util.LongBits(message.size.low >>> 0, message.size.high >>> 0).toNumber(true) : message.size;
            if (message.modified_time != null && message.hasOwnProperty("modified_time"))
                if (typeof message.modified_time === "number")
                    object.modified_time = options.longs === String ? String(message.modified_time) : message.modified_time;
                else
                    object.modified_time = options.longs === String ? $util.Long.prototype.toString.call(message.modified_time) : options.longs === Number ? new $util.LongBits(message.modified_time.low >>> 0, message.modified_time.high >>> 0).toNumber(true) : message.modified_time;
            return object;
        };

        /**
         * Converts this FileEntry to JSON.
         * @function toJSON
         * @memberof hbb.FileEntry
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        FileEntry.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for FileEntry
         * @function getTypeUrl
         * @memberof hbb.FileEntry
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        FileEntry.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.FileEntry";
        };

        return FileEntry;
    })();

    hbb.FileDirectory = (function() {

        /**
         * Properties of a FileDirectory.
         * @memberof hbb
         * @interface IFileDirectory
         * @property {number|null} [id] FileDirectory id
         * @property {string|null} [path] FileDirectory path
         * @property {Array.<hbb.IFileEntry>|null} [entries] FileDirectory entries
         */

        /**
         * Constructs a new FileDirectory.
         * @memberof hbb
         * @classdesc Represents a FileDirectory.
         * @implements IFileDirectory
         * @constructor
         * @param {hbb.IFileDirectory=} [properties] Properties to set
         */
        function FileDirectory(properties) {
            this.entries = [];
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * FileDirectory id.
         * @member {number} id
         * @memberof hbb.FileDirectory
         * @instance
         */
        FileDirectory.prototype.id = 0;

        /**
         * FileDirectory path.
         * @member {string} path
         * @memberof hbb.FileDirectory
         * @instance
         */
        FileDirectory.prototype.path = "";

        /**
         * FileDirectory entries.
         * @member {Array.<hbb.IFileEntry>} entries
         * @memberof hbb.FileDirectory
         * @instance
         */
        FileDirectory.prototype.entries = $util.emptyArray;

        /**
         * Creates a new FileDirectory instance using the specified properties.
         * @function create
         * @memberof hbb.FileDirectory
         * @static
         * @param {hbb.IFileDirectory=} [properties] Properties to set
         * @returns {hbb.FileDirectory} FileDirectory instance
         */
        FileDirectory.create = function create(properties) {
            return new FileDirectory(properties);
        };

        /**
         * Encodes the specified FileDirectory message. Does not implicitly {@link hbb.FileDirectory.verify|verify} messages.
         * @function encode
         * @memberof hbb.FileDirectory
         * @static
         * @param {hbb.IFileDirectory} message FileDirectory message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FileDirectory.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.id != null && Object.hasOwnProperty.call(message, "id"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.id);
            if (message.path != null && Object.hasOwnProperty.call(message, "path"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.path);
            if (message.entries != null && message.entries.length)
                for (let i = 0; i < message.entries.length; ++i)
                    $root.hbb.FileEntry.encode(message.entries[i], writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified FileDirectory message, length delimited. Does not implicitly {@link hbb.FileDirectory.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.FileDirectory
         * @static
         * @param {hbb.IFileDirectory} message FileDirectory message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FileDirectory.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a FileDirectory message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.FileDirectory
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.FileDirectory} FileDirectory
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FileDirectory.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.FileDirectory();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.id = reader.int32();
                        break;
                    }
                case 2: {
                        message.path = reader.string();
                        break;
                    }
                case 3: {
                        if (!(message.entries && message.entries.length))
                            message.entries = [];
                        message.entries.push($root.hbb.FileEntry.decode(reader, reader.uint32(), undefined, long + 1));
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a FileDirectory message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.FileDirectory
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.FileDirectory} FileDirectory
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FileDirectory.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a FileDirectory message.
         * @function verify
         * @memberof hbb.FileDirectory
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        FileDirectory.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.id != null && message.hasOwnProperty("id"))
                if (!$util.isInteger(message.id))
                    return "id: integer expected";
            if (message.path != null && message.hasOwnProperty("path"))
                if (!$util.isString(message.path))
                    return "path: string expected";
            if (message.entries != null && message.hasOwnProperty("entries")) {
                if (!Array.isArray(message.entries))
                    return "entries: array expected";
                for (let i = 0; i < message.entries.length; ++i) {
                    let error = $root.hbb.FileEntry.verify(message.entries[i], long + 1);
                    if (error)
                        return "entries." + error;
                }
            }
            return null;
        };

        /**
         * Creates a FileDirectory message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.FileDirectory
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.FileDirectory} FileDirectory
         */
        FileDirectory.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.FileDirectory)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.FileDirectory();
            if (object.id != null)
                message.id = object.id | 0;
            if (object.path != null)
                message.path = String(object.path);
            if (object.entries) {
                if (!Array.isArray(object.entries))
                    throw TypeError(".hbb.FileDirectory.entries: array expected");
                message.entries = [];
                for (let i = 0; i < object.entries.length; ++i) {
                    if (typeof object.entries[i] !== "object")
                        throw TypeError(".hbb.FileDirectory.entries: object expected");
                    message.entries[i] = $root.hbb.FileEntry.fromObject(object.entries[i], long + 1);
                }
            }
            return message;
        };

        /**
         * Creates a plain object from a FileDirectory message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.FileDirectory
         * @static
         * @param {hbb.FileDirectory} message FileDirectory
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        FileDirectory.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.arrays || options.defaults)
                object.entries = [];
            if (options.defaults) {
                object.id = 0;
                object.path = "";
            }
            if (message.id != null && message.hasOwnProperty("id"))
                object.id = message.id;
            if (message.path != null && message.hasOwnProperty("path"))
                object.path = message.path;
            if (message.entries && message.entries.length) {
                object.entries = [];
                for (let j = 0; j < message.entries.length; ++j)
                    object.entries[j] = $root.hbb.FileEntry.toObject(message.entries[j], options);
            }
            return object;
        };

        /**
         * Converts this FileDirectory to JSON.
         * @function toJSON
         * @memberof hbb.FileDirectory
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        FileDirectory.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for FileDirectory
         * @function getTypeUrl
         * @memberof hbb.FileDirectory
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        FileDirectory.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.FileDirectory";
        };

        return FileDirectory;
    })();

    hbb.ReadDir = (function() {

        /**
         * Properties of a ReadDir.
         * @memberof hbb
         * @interface IReadDir
         * @property {string|null} [path] ReadDir path
         * @property {boolean|null} [include_hidden] ReadDir include_hidden
         */

        /**
         * Constructs a new ReadDir.
         * @memberof hbb
         * @classdesc Represents a ReadDir.
         * @implements IReadDir
         * @constructor
         * @param {hbb.IReadDir=} [properties] Properties to set
         */
        function ReadDir(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ReadDir path.
         * @member {string} path
         * @memberof hbb.ReadDir
         * @instance
         */
        ReadDir.prototype.path = "";

        /**
         * ReadDir include_hidden.
         * @member {boolean} include_hidden
         * @memberof hbb.ReadDir
         * @instance
         */
        ReadDir.prototype.include_hidden = false;

        /**
         * Creates a new ReadDir instance using the specified properties.
         * @function create
         * @memberof hbb.ReadDir
         * @static
         * @param {hbb.IReadDir=} [properties] Properties to set
         * @returns {hbb.ReadDir} ReadDir instance
         */
        ReadDir.create = function create(properties) {
            return new ReadDir(properties);
        };

        /**
         * Encodes the specified ReadDir message. Does not implicitly {@link hbb.ReadDir.verify|verify} messages.
         * @function encode
         * @memberof hbb.ReadDir
         * @static
         * @param {hbb.IReadDir} message ReadDir message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ReadDir.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.path != null && Object.hasOwnProperty.call(message, "path"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.path);
            if (message.include_hidden != null && Object.hasOwnProperty.call(message, "include_hidden"))
                writer.uint32(/* id 2, wireType 0 =*/16).bool(message.include_hidden);
            return writer;
        };

        /**
         * Encodes the specified ReadDir message, length delimited. Does not implicitly {@link hbb.ReadDir.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.ReadDir
         * @static
         * @param {hbb.IReadDir} message ReadDir message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ReadDir.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a ReadDir message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.ReadDir
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.ReadDir} ReadDir
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ReadDir.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.ReadDir();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.path = reader.string();
                        break;
                    }
                case 2: {
                        message.include_hidden = reader.bool();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a ReadDir message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.ReadDir
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.ReadDir} ReadDir
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ReadDir.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a ReadDir message.
         * @function verify
         * @memberof hbb.ReadDir
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ReadDir.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.path != null && message.hasOwnProperty("path"))
                if (!$util.isString(message.path))
                    return "path: string expected";
            if (message.include_hidden != null && message.hasOwnProperty("include_hidden"))
                if (typeof message.include_hidden !== "boolean")
                    return "include_hidden: boolean expected";
            return null;
        };

        /**
         * Creates a ReadDir message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.ReadDir
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.ReadDir} ReadDir
         */
        ReadDir.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.ReadDir)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.ReadDir();
            if (object.path != null)
                message.path = String(object.path);
            if (object.include_hidden != null)
                message.include_hidden = Boolean(object.include_hidden);
            return message;
        };

        /**
         * Creates a plain object from a ReadDir message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.ReadDir
         * @static
         * @param {hbb.ReadDir} message ReadDir
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ReadDir.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.path = "";
                object.include_hidden = false;
            }
            if (message.path != null && message.hasOwnProperty("path"))
                object.path = message.path;
            if (message.include_hidden != null && message.hasOwnProperty("include_hidden"))
                object.include_hidden = message.include_hidden;
            return object;
        };

        /**
         * Converts this ReadDir to JSON.
         * @function toJSON
         * @memberof hbb.ReadDir
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ReadDir.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for ReadDir
         * @function getTypeUrl
         * @memberof hbb.ReadDir
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        ReadDir.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.ReadDir";
        };

        return ReadDir;
    })();

    hbb.ReadEmptyDirs = (function() {

        /**
         * Properties of a ReadEmptyDirs.
         * @memberof hbb
         * @interface IReadEmptyDirs
         * @property {string|null} [path] ReadEmptyDirs path
         * @property {boolean|null} [include_hidden] ReadEmptyDirs include_hidden
         */

        /**
         * Constructs a new ReadEmptyDirs.
         * @memberof hbb
         * @classdesc Represents a ReadEmptyDirs.
         * @implements IReadEmptyDirs
         * @constructor
         * @param {hbb.IReadEmptyDirs=} [properties] Properties to set
         */
        function ReadEmptyDirs(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ReadEmptyDirs path.
         * @member {string} path
         * @memberof hbb.ReadEmptyDirs
         * @instance
         */
        ReadEmptyDirs.prototype.path = "";

        /**
         * ReadEmptyDirs include_hidden.
         * @member {boolean} include_hidden
         * @memberof hbb.ReadEmptyDirs
         * @instance
         */
        ReadEmptyDirs.prototype.include_hidden = false;

        /**
         * Creates a new ReadEmptyDirs instance using the specified properties.
         * @function create
         * @memberof hbb.ReadEmptyDirs
         * @static
         * @param {hbb.IReadEmptyDirs=} [properties] Properties to set
         * @returns {hbb.ReadEmptyDirs} ReadEmptyDirs instance
         */
        ReadEmptyDirs.create = function create(properties) {
            return new ReadEmptyDirs(properties);
        };

        /**
         * Encodes the specified ReadEmptyDirs message. Does not implicitly {@link hbb.ReadEmptyDirs.verify|verify} messages.
         * @function encode
         * @memberof hbb.ReadEmptyDirs
         * @static
         * @param {hbb.IReadEmptyDirs} message ReadEmptyDirs message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ReadEmptyDirs.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.path != null && Object.hasOwnProperty.call(message, "path"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.path);
            if (message.include_hidden != null && Object.hasOwnProperty.call(message, "include_hidden"))
                writer.uint32(/* id 2, wireType 0 =*/16).bool(message.include_hidden);
            return writer;
        };

        /**
         * Encodes the specified ReadEmptyDirs message, length delimited. Does not implicitly {@link hbb.ReadEmptyDirs.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.ReadEmptyDirs
         * @static
         * @param {hbb.IReadEmptyDirs} message ReadEmptyDirs message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ReadEmptyDirs.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a ReadEmptyDirs message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.ReadEmptyDirs
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.ReadEmptyDirs} ReadEmptyDirs
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ReadEmptyDirs.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.ReadEmptyDirs();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.path = reader.string();
                        break;
                    }
                case 2: {
                        message.include_hidden = reader.bool();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a ReadEmptyDirs message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.ReadEmptyDirs
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.ReadEmptyDirs} ReadEmptyDirs
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ReadEmptyDirs.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a ReadEmptyDirs message.
         * @function verify
         * @memberof hbb.ReadEmptyDirs
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ReadEmptyDirs.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.path != null && message.hasOwnProperty("path"))
                if (!$util.isString(message.path))
                    return "path: string expected";
            if (message.include_hidden != null && message.hasOwnProperty("include_hidden"))
                if (typeof message.include_hidden !== "boolean")
                    return "include_hidden: boolean expected";
            return null;
        };

        /**
         * Creates a ReadEmptyDirs message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.ReadEmptyDirs
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.ReadEmptyDirs} ReadEmptyDirs
         */
        ReadEmptyDirs.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.ReadEmptyDirs)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.ReadEmptyDirs();
            if (object.path != null)
                message.path = String(object.path);
            if (object.include_hidden != null)
                message.include_hidden = Boolean(object.include_hidden);
            return message;
        };

        /**
         * Creates a plain object from a ReadEmptyDirs message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.ReadEmptyDirs
         * @static
         * @param {hbb.ReadEmptyDirs} message ReadEmptyDirs
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ReadEmptyDirs.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.path = "";
                object.include_hidden = false;
            }
            if (message.path != null && message.hasOwnProperty("path"))
                object.path = message.path;
            if (message.include_hidden != null && message.hasOwnProperty("include_hidden"))
                object.include_hidden = message.include_hidden;
            return object;
        };

        /**
         * Converts this ReadEmptyDirs to JSON.
         * @function toJSON
         * @memberof hbb.ReadEmptyDirs
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ReadEmptyDirs.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for ReadEmptyDirs
         * @function getTypeUrl
         * @memberof hbb.ReadEmptyDirs
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        ReadEmptyDirs.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.ReadEmptyDirs";
        };

        return ReadEmptyDirs;
    })();

    hbb.ReadEmptyDirsResponse = (function() {

        /**
         * Properties of a ReadEmptyDirsResponse.
         * @memberof hbb
         * @interface IReadEmptyDirsResponse
         * @property {string|null} [path] ReadEmptyDirsResponse path
         * @property {Array.<hbb.IFileDirectory>|null} [empty_dirs] ReadEmptyDirsResponse empty_dirs
         */

        /**
         * Constructs a new ReadEmptyDirsResponse.
         * @memberof hbb
         * @classdesc Represents a ReadEmptyDirsResponse.
         * @implements IReadEmptyDirsResponse
         * @constructor
         * @param {hbb.IReadEmptyDirsResponse=} [properties] Properties to set
         */
        function ReadEmptyDirsResponse(properties) {
            this.empty_dirs = [];
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ReadEmptyDirsResponse path.
         * @member {string} path
         * @memberof hbb.ReadEmptyDirsResponse
         * @instance
         */
        ReadEmptyDirsResponse.prototype.path = "";

        /**
         * ReadEmptyDirsResponse empty_dirs.
         * @member {Array.<hbb.IFileDirectory>} empty_dirs
         * @memberof hbb.ReadEmptyDirsResponse
         * @instance
         */
        ReadEmptyDirsResponse.prototype.empty_dirs = $util.emptyArray;

        /**
         * Creates a new ReadEmptyDirsResponse instance using the specified properties.
         * @function create
         * @memberof hbb.ReadEmptyDirsResponse
         * @static
         * @param {hbb.IReadEmptyDirsResponse=} [properties] Properties to set
         * @returns {hbb.ReadEmptyDirsResponse} ReadEmptyDirsResponse instance
         */
        ReadEmptyDirsResponse.create = function create(properties) {
            return new ReadEmptyDirsResponse(properties);
        };

        /**
         * Encodes the specified ReadEmptyDirsResponse message. Does not implicitly {@link hbb.ReadEmptyDirsResponse.verify|verify} messages.
         * @function encode
         * @memberof hbb.ReadEmptyDirsResponse
         * @static
         * @param {hbb.IReadEmptyDirsResponse} message ReadEmptyDirsResponse message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ReadEmptyDirsResponse.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.path != null && Object.hasOwnProperty.call(message, "path"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.path);
            if (message.empty_dirs != null && message.empty_dirs.length)
                for (let i = 0; i < message.empty_dirs.length; ++i)
                    $root.hbb.FileDirectory.encode(message.empty_dirs[i], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified ReadEmptyDirsResponse message, length delimited. Does not implicitly {@link hbb.ReadEmptyDirsResponse.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.ReadEmptyDirsResponse
         * @static
         * @param {hbb.IReadEmptyDirsResponse} message ReadEmptyDirsResponse message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ReadEmptyDirsResponse.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a ReadEmptyDirsResponse message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.ReadEmptyDirsResponse
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.ReadEmptyDirsResponse} ReadEmptyDirsResponse
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ReadEmptyDirsResponse.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.ReadEmptyDirsResponse();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.path = reader.string();
                        break;
                    }
                case 2: {
                        if (!(message.empty_dirs && message.empty_dirs.length))
                            message.empty_dirs = [];
                        message.empty_dirs.push($root.hbb.FileDirectory.decode(reader, reader.uint32(), undefined, long + 1));
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a ReadEmptyDirsResponse message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.ReadEmptyDirsResponse
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.ReadEmptyDirsResponse} ReadEmptyDirsResponse
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ReadEmptyDirsResponse.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a ReadEmptyDirsResponse message.
         * @function verify
         * @memberof hbb.ReadEmptyDirsResponse
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ReadEmptyDirsResponse.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.path != null && message.hasOwnProperty("path"))
                if (!$util.isString(message.path))
                    return "path: string expected";
            if (message.empty_dirs != null && message.hasOwnProperty("empty_dirs")) {
                if (!Array.isArray(message.empty_dirs))
                    return "empty_dirs: array expected";
                for (let i = 0; i < message.empty_dirs.length; ++i) {
                    let error = $root.hbb.FileDirectory.verify(message.empty_dirs[i], long + 1);
                    if (error)
                        return "empty_dirs." + error;
                }
            }
            return null;
        };

        /**
         * Creates a ReadEmptyDirsResponse message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.ReadEmptyDirsResponse
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.ReadEmptyDirsResponse} ReadEmptyDirsResponse
         */
        ReadEmptyDirsResponse.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.ReadEmptyDirsResponse)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.ReadEmptyDirsResponse();
            if (object.path != null)
                message.path = String(object.path);
            if (object.empty_dirs) {
                if (!Array.isArray(object.empty_dirs))
                    throw TypeError(".hbb.ReadEmptyDirsResponse.empty_dirs: array expected");
                message.empty_dirs = [];
                for (let i = 0; i < object.empty_dirs.length; ++i) {
                    if (typeof object.empty_dirs[i] !== "object")
                        throw TypeError(".hbb.ReadEmptyDirsResponse.empty_dirs: object expected");
                    message.empty_dirs[i] = $root.hbb.FileDirectory.fromObject(object.empty_dirs[i], long + 1);
                }
            }
            return message;
        };

        /**
         * Creates a plain object from a ReadEmptyDirsResponse message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.ReadEmptyDirsResponse
         * @static
         * @param {hbb.ReadEmptyDirsResponse} message ReadEmptyDirsResponse
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ReadEmptyDirsResponse.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.arrays || options.defaults)
                object.empty_dirs = [];
            if (options.defaults)
                object.path = "";
            if (message.path != null && message.hasOwnProperty("path"))
                object.path = message.path;
            if (message.empty_dirs && message.empty_dirs.length) {
                object.empty_dirs = [];
                for (let j = 0; j < message.empty_dirs.length; ++j)
                    object.empty_dirs[j] = $root.hbb.FileDirectory.toObject(message.empty_dirs[j], options);
            }
            return object;
        };

        /**
         * Converts this ReadEmptyDirsResponse to JSON.
         * @function toJSON
         * @memberof hbb.ReadEmptyDirsResponse
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ReadEmptyDirsResponse.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for ReadEmptyDirsResponse
         * @function getTypeUrl
         * @memberof hbb.ReadEmptyDirsResponse
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        ReadEmptyDirsResponse.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.ReadEmptyDirsResponse";
        };

        return ReadEmptyDirsResponse;
    })();

    hbb.ReadAllFiles = (function() {

        /**
         * Properties of a ReadAllFiles.
         * @memberof hbb
         * @interface IReadAllFiles
         * @property {number|null} [id] ReadAllFiles id
         * @property {string|null} [path] ReadAllFiles path
         * @property {boolean|null} [include_hidden] ReadAllFiles include_hidden
         */

        /**
         * Constructs a new ReadAllFiles.
         * @memberof hbb
         * @classdesc Represents a ReadAllFiles.
         * @implements IReadAllFiles
         * @constructor
         * @param {hbb.IReadAllFiles=} [properties] Properties to set
         */
        function ReadAllFiles(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ReadAllFiles id.
         * @member {number} id
         * @memberof hbb.ReadAllFiles
         * @instance
         */
        ReadAllFiles.prototype.id = 0;

        /**
         * ReadAllFiles path.
         * @member {string} path
         * @memberof hbb.ReadAllFiles
         * @instance
         */
        ReadAllFiles.prototype.path = "";

        /**
         * ReadAllFiles include_hidden.
         * @member {boolean} include_hidden
         * @memberof hbb.ReadAllFiles
         * @instance
         */
        ReadAllFiles.prototype.include_hidden = false;

        /**
         * Creates a new ReadAllFiles instance using the specified properties.
         * @function create
         * @memberof hbb.ReadAllFiles
         * @static
         * @param {hbb.IReadAllFiles=} [properties] Properties to set
         * @returns {hbb.ReadAllFiles} ReadAllFiles instance
         */
        ReadAllFiles.create = function create(properties) {
            return new ReadAllFiles(properties);
        };

        /**
         * Encodes the specified ReadAllFiles message. Does not implicitly {@link hbb.ReadAllFiles.verify|verify} messages.
         * @function encode
         * @memberof hbb.ReadAllFiles
         * @static
         * @param {hbb.IReadAllFiles} message ReadAllFiles message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ReadAllFiles.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.id != null && Object.hasOwnProperty.call(message, "id"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.id);
            if (message.path != null && Object.hasOwnProperty.call(message, "path"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.path);
            if (message.include_hidden != null && Object.hasOwnProperty.call(message, "include_hidden"))
                writer.uint32(/* id 3, wireType 0 =*/24).bool(message.include_hidden);
            return writer;
        };

        /**
         * Encodes the specified ReadAllFiles message, length delimited. Does not implicitly {@link hbb.ReadAllFiles.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.ReadAllFiles
         * @static
         * @param {hbb.IReadAllFiles} message ReadAllFiles message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ReadAllFiles.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a ReadAllFiles message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.ReadAllFiles
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.ReadAllFiles} ReadAllFiles
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ReadAllFiles.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.ReadAllFiles();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.id = reader.int32();
                        break;
                    }
                case 2: {
                        message.path = reader.string();
                        break;
                    }
                case 3: {
                        message.include_hidden = reader.bool();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a ReadAllFiles message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.ReadAllFiles
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.ReadAllFiles} ReadAllFiles
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ReadAllFiles.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a ReadAllFiles message.
         * @function verify
         * @memberof hbb.ReadAllFiles
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ReadAllFiles.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.id != null && message.hasOwnProperty("id"))
                if (!$util.isInteger(message.id))
                    return "id: integer expected";
            if (message.path != null && message.hasOwnProperty("path"))
                if (!$util.isString(message.path))
                    return "path: string expected";
            if (message.include_hidden != null && message.hasOwnProperty("include_hidden"))
                if (typeof message.include_hidden !== "boolean")
                    return "include_hidden: boolean expected";
            return null;
        };

        /**
         * Creates a ReadAllFiles message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.ReadAllFiles
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.ReadAllFiles} ReadAllFiles
         */
        ReadAllFiles.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.ReadAllFiles)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.ReadAllFiles();
            if (object.id != null)
                message.id = object.id | 0;
            if (object.path != null)
                message.path = String(object.path);
            if (object.include_hidden != null)
                message.include_hidden = Boolean(object.include_hidden);
            return message;
        };

        /**
         * Creates a plain object from a ReadAllFiles message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.ReadAllFiles
         * @static
         * @param {hbb.ReadAllFiles} message ReadAllFiles
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ReadAllFiles.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.id = 0;
                object.path = "";
                object.include_hidden = false;
            }
            if (message.id != null && message.hasOwnProperty("id"))
                object.id = message.id;
            if (message.path != null && message.hasOwnProperty("path"))
                object.path = message.path;
            if (message.include_hidden != null && message.hasOwnProperty("include_hidden"))
                object.include_hidden = message.include_hidden;
            return object;
        };

        /**
         * Converts this ReadAllFiles to JSON.
         * @function toJSON
         * @memberof hbb.ReadAllFiles
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ReadAllFiles.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for ReadAllFiles
         * @function getTypeUrl
         * @memberof hbb.ReadAllFiles
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        ReadAllFiles.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.ReadAllFiles";
        };

        return ReadAllFiles;
    })();

    hbb.FileRename = (function() {

        /**
         * Properties of a FileRename.
         * @memberof hbb
         * @interface IFileRename
         * @property {number|null} [id] FileRename id
         * @property {string|null} [path] FileRename path
         * @property {string|null} [new_name] FileRename new_name
         */

        /**
         * Constructs a new FileRename.
         * @memberof hbb
         * @classdesc Represents a FileRename.
         * @implements IFileRename
         * @constructor
         * @param {hbb.IFileRename=} [properties] Properties to set
         */
        function FileRename(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * FileRename id.
         * @member {number} id
         * @memberof hbb.FileRename
         * @instance
         */
        FileRename.prototype.id = 0;

        /**
         * FileRename path.
         * @member {string} path
         * @memberof hbb.FileRename
         * @instance
         */
        FileRename.prototype.path = "";

        /**
         * FileRename new_name.
         * @member {string} new_name
         * @memberof hbb.FileRename
         * @instance
         */
        FileRename.prototype.new_name = "";

        /**
         * Creates a new FileRename instance using the specified properties.
         * @function create
         * @memberof hbb.FileRename
         * @static
         * @param {hbb.IFileRename=} [properties] Properties to set
         * @returns {hbb.FileRename} FileRename instance
         */
        FileRename.create = function create(properties) {
            return new FileRename(properties);
        };

        /**
         * Encodes the specified FileRename message. Does not implicitly {@link hbb.FileRename.verify|verify} messages.
         * @function encode
         * @memberof hbb.FileRename
         * @static
         * @param {hbb.IFileRename} message FileRename message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FileRename.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.id != null && Object.hasOwnProperty.call(message, "id"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.id);
            if (message.path != null && Object.hasOwnProperty.call(message, "path"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.path);
            if (message.new_name != null && Object.hasOwnProperty.call(message, "new_name"))
                writer.uint32(/* id 3, wireType 2 =*/26).string(message.new_name);
            return writer;
        };

        /**
         * Encodes the specified FileRename message, length delimited. Does not implicitly {@link hbb.FileRename.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.FileRename
         * @static
         * @param {hbb.IFileRename} message FileRename message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FileRename.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a FileRename message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.FileRename
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.FileRename} FileRename
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FileRename.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.FileRename();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.id = reader.int32();
                        break;
                    }
                case 2: {
                        message.path = reader.string();
                        break;
                    }
                case 3: {
                        message.new_name = reader.string();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a FileRename message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.FileRename
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.FileRename} FileRename
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FileRename.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a FileRename message.
         * @function verify
         * @memberof hbb.FileRename
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        FileRename.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.id != null && message.hasOwnProperty("id"))
                if (!$util.isInteger(message.id))
                    return "id: integer expected";
            if (message.path != null && message.hasOwnProperty("path"))
                if (!$util.isString(message.path))
                    return "path: string expected";
            if (message.new_name != null && message.hasOwnProperty("new_name"))
                if (!$util.isString(message.new_name))
                    return "new_name: string expected";
            return null;
        };

        /**
         * Creates a FileRename message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.FileRename
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.FileRename} FileRename
         */
        FileRename.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.FileRename)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.FileRename();
            if (object.id != null)
                message.id = object.id | 0;
            if (object.path != null)
                message.path = String(object.path);
            if (object.new_name != null)
                message.new_name = String(object.new_name);
            return message;
        };

        /**
         * Creates a plain object from a FileRename message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.FileRename
         * @static
         * @param {hbb.FileRename} message FileRename
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        FileRename.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.id = 0;
                object.path = "";
                object.new_name = "";
            }
            if (message.id != null && message.hasOwnProperty("id"))
                object.id = message.id;
            if (message.path != null && message.hasOwnProperty("path"))
                object.path = message.path;
            if (message.new_name != null && message.hasOwnProperty("new_name"))
                object.new_name = message.new_name;
            return object;
        };

        /**
         * Converts this FileRename to JSON.
         * @function toJSON
         * @memberof hbb.FileRename
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        FileRename.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for FileRename
         * @function getTypeUrl
         * @memberof hbb.FileRename
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        FileRename.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.FileRename";
        };

        return FileRename;
    })();

    hbb.FileAction = (function() {

        /**
         * Properties of a FileAction.
         * @memberof hbb
         * @interface IFileAction
         * @property {hbb.IReadDir|null} [read_dir] FileAction read_dir
         * @property {hbb.IFileTransferSendRequest|null} [send] FileAction send
         * @property {hbb.IFileTransferReceiveRequest|null} [receive] FileAction receive
         * @property {hbb.IFileDirCreate|null} [create] FileAction create
         * @property {hbb.IFileRemoveDir|null} [remove_dir] FileAction remove_dir
         * @property {hbb.IFileRemoveFile|null} [remove_file] FileAction remove_file
         * @property {hbb.IReadAllFiles|null} [all_files] FileAction all_files
         * @property {hbb.IFileTransferCancel|null} [cancel] FileAction cancel
         * @property {hbb.IFileTransferSendConfirmRequest|null} [send_confirm] FileAction send_confirm
         * @property {hbb.IFileRename|null} [rename] FileAction rename
         * @property {hbb.IReadEmptyDirs|null} [read_empty_dirs] FileAction read_empty_dirs
         */

        /**
         * Constructs a new FileAction.
         * @memberof hbb
         * @classdesc Represents a FileAction.
         * @implements IFileAction
         * @constructor
         * @param {hbb.IFileAction=} [properties] Properties to set
         */
        function FileAction(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * FileAction read_dir.
         * @member {hbb.IReadDir|null|undefined} read_dir
         * @memberof hbb.FileAction
         * @instance
         */
        FileAction.prototype.read_dir = null;

        /**
         * FileAction send.
         * @member {hbb.IFileTransferSendRequest|null|undefined} send
         * @memberof hbb.FileAction
         * @instance
         */
        FileAction.prototype.send = null;

        /**
         * FileAction receive.
         * @member {hbb.IFileTransferReceiveRequest|null|undefined} receive
         * @memberof hbb.FileAction
         * @instance
         */
        FileAction.prototype.receive = null;

        /**
         * FileAction create.
         * @member {hbb.IFileDirCreate|null|undefined} create
         * @memberof hbb.FileAction
         * @instance
         */
        FileAction.prototype.create = null;

        /**
         * FileAction remove_dir.
         * @member {hbb.IFileRemoveDir|null|undefined} remove_dir
         * @memberof hbb.FileAction
         * @instance
         */
        FileAction.prototype.remove_dir = null;

        /**
         * FileAction remove_file.
         * @member {hbb.IFileRemoveFile|null|undefined} remove_file
         * @memberof hbb.FileAction
         * @instance
         */
        FileAction.prototype.remove_file = null;

        /**
         * FileAction all_files.
         * @member {hbb.IReadAllFiles|null|undefined} all_files
         * @memberof hbb.FileAction
         * @instance
         */
        FileAction.prototype.all_files = null;

        /**
         * FileAction cancel.
         * @member {hbb.IFileTransferCancel|null|undefined} cancel
         * @memberof hbb.FileAction
         * @instance
         */
        FileAction.prototype.cancel = null;

        /**
         * FileAction send_confirm.
         * @member {hbb.IFileTransferSendConfirmRequest|null|undefined} send_confirm
         * @memberof hbb.FileAction
         * @instance
         */
        FileAction.prototype.send_confirm = null;

        /**
         * FileAction rename.
         * @member {hbb.IFileRename|null|undefined} rename
         * @memberof hbb.FileAction
         * @instance
         */
        FileAction.prototype.rename = null;

        /**
         * FileAction read_empty_dirs.
         * @member {hbb.IReadEmptyDirs|null|undefined} read_empty_dirs
         * @memberof hbb.FileAction
         * @instance
         */
        FileAction.prototype.read_empty_dirs = null;

        // OneOf field names bound to virtual getters and setters
        let $oneOfFields;

        /**
         * FileAction union.
         * @member {"read_dir"|"send"|"receive"|"create"|"remove_dir"|"remove_file"|"all_files"|"cancel"|"send_confirm"|"rename"|"read_empty_dirs"|undefined} union
         * @memberof hbb.FileAction
         * @instance
         */
        Object.defineProperty(FileAction.prototype, "union", {
            get: $util.oneOfGetter($oneOfFields = ["read_dir", "send", "receive", "create", "remove_dir", "remove_file", "all_files", "cancel", "send_confirm", "rename", "read_empty_dirs"]),
            set: $util.oneOfSetter($oneOfFields)
        });

        /**
         * Creates a new FileAction instance using the specified properties.
         * @function create
         * @memberof hbb.FileAction
         * @static
         * @param {hbb.IFileAction=} [properties] Properties to set
         * @returns {hbb.FileAction} FileAction instance
         */
        FileAction.create = function create(properties) {
            return new FileAction(properties);
        };

        /**
         * Encodes the specified FileAction message. Does not implicitly {@link hbb.FileAction.verify|verify} messages.
         * @function encode
         * @memberof hbb.FileAction
         * @static
         * @param {hbb.IFileAction} message FileAction message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FileAction.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.read_dir != null && Object.hasOwnProperty.call(message, "read_dir"))
                $root.hbb.ReadDir.encode(message.read_dir, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.send != null && Object.hasOwnProperty.call(message, "send"))
                $root.hbb.FileTransferSendRequest.encode(message.send, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            if (message.receive != null && Object.hasOwnProperty.call(message, "receive"))
                $root.hbb.FileTransferReceiveRequest.encode(message.receive, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
            if (message.create != null && Object.hasOwnProperty.call(message, "create"))
                $root.hbb.FileDirCreate.encode(message.create, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim();
            if (message.remove_dir != null && Object.hasOwnProperty.call(message, "remove_dir"))
                $root.hbb.FileRemoveDir.encode(message.remove_dir, writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim();
            if (message.remove_file != null && Object.hasOwnProperty.call(message, "remove_file"))
                $root.hbb.FileRemoveFile.encode(message.remove_file, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim();
            if (message.all_files != null && Object.hasOwnProperty.call(message, "all_files"))
                $root.hbb.ReadAllFiles.encode(message.all_files, writer.uint32(/* id 7, wireType 2 =*/58).fork()).ldelim();
            if (message.cancel != null && Object.hasOwnProperty.call(message, "cancel"))
                $root.hbb.FileTransferCancel.encode(message.cancel, writer.uint32(/* id 8, wireType 2 =*/66).fork()).ldelim();
            if (message.send_confirm != null && Object.hasOwnProperty.call(message, "send_confirm"))
                $root.hbb.FileTransferSendConfirmRequest.encode(message.send_confirm, writer.uint32(/* id 9, wireType 2 =*/74).fork()).ldelim();
            if (message.rename != null && Object.hasOwnProperty.call(message, "rename"))
                $root.hbb.FileRename.encode(message.rename, writer.uint32(/* id 10, wireType 2 =*/82).fork()).ldelim();
            if (message.read_empty_dirs != null && Object.hasOwnProperty.call(message, "read_empty_dirs"))
                $root.hbb.ReadEmptyDirs.encode(message.read_empty_dirs, writer.uint32(/* id 11, wireType 2 =*/90).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified FileAction message, length delimited. Does not implicitly {@link hbb.FileAction.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.FileAction
         * @static
         * @param {hbb.IFileAction} message FileAction message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FileAction.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a FileAction message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.FileAction
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.FileAction} FileAction
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FileAction.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.FileAction();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.read_dir = $root.hbb.ReadDir.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 2: {
                        message.send = $root.hbb.FileTransferSendRequest.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 3: {
                        message.receive = $root.hbb.FileTransferReceiveRequest.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 4: {
                        message.create = $root.hbb.FileDirCreate.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 5: {
                        message.remove_dir = $root.hbb.FileRemoveDir.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 6: {
                        message.remove_file = $root.hbb.FileRemoveFile.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 7: {
                        message.all_files = $root.hbb.ReadAllFiles.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 8: {
                        message.cancel = $root.hbb.FileTransferCancel.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 9: {
                        message.send_confirm = $root.hbb.FileTransferSendConfirmRequest.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 10: {
                        message.rename = $root.hbb.FileRename.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 11: {
                        message.read_empty_dirs = $root.hbb.ReadEmptyDirs.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a FileAction message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.FileAction
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.FileAction} FileAction
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FileAction.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a FileAction message.
         * @function verify
         * @memberof hbb.FileAction
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        FileAction.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            let properties = {};
            if (message.read_dir != null && message.hasOwnProperty("read_dir")) {
                properties.union = 1;
                {
                    let error = $root.hbb.ReadDir.verify(message.read_dir, long + 1);
                    if (error)
                        return "read_dir." + error;
                }
            }
            if (message.send != null && message.hasOwnProperty("send")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.FileTransferSendRequest.verify(message.send, long + 1);
                    if (error)
                        return "send." + error;
                }
            }
            if (message.receive != null && message.hasOwnProperty("receive")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.FileTransferReceiveRequest.verify(message.receive, long + 1);
                    if (error)
                        return "receive." + error;
                }
            }
            if (message.create != null && message.hasOwnProperty("create")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.FileDirCreate.verify(message.create, long + 1);
                    if (error)
                        return "create." + error;
                }
            }
            if (message.remove_dir != null && message.hasOwnProperty("remove_dir")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.FileRemoveDir.verify(message.remove_dir, long + 1);
                    if (error)
                        return "remove_dir." + error;
                }
            }
            if (message.remove_file != null && message.hasOwnProperty("remove_file")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.FileRemoveFile.verify(message.remove_file, long + 1);
                    if (error)
                        return "remove_file." + error;
                }
            }
            if (message.all_files != null && message.hasOwnProperty("all_files")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.ReadAllFiles.verify(message.all_files, long + 1);
                    if (error)
                        return "all_files." + error;
                }
            }
            if (message.cancel != null && message.hasOwnProperty("cancel")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.FileTransferCancel.verify(message.cancel, long + 1);
                    if (error)
                        return "cancel." + error;
                }
            }
            if (message.send_confirm != null && message.hasOwnProperty("send_confirm")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.FileTransferSendConfirmRequest.verify(message.send_confirm, long + 1);
                    if (error)
                        return "send_confirm." + error;
                }
            }
            if (message.rename != null && message.hasOwnProperty("rename")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.FileRename.verify(message.rename, long + 1);
                    if (error)
                        return "rename." + error;
                }
            }
            if (message.read_empty_dirs != null && message.hasOwnProperty("read_empty_dirs")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.ReadEmptyDirs.verify(message.read_empty_dirs, long + 1);
                    if (error)
                        return "read_empty_dirs." + error;
                }
            }
            return null;
        };

        /**
         * Creates a FileAction message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.FileAction
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.FileAction} FileAction
         */
        FileAction.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.FileAction)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.FileAction();
            if (object.read_dir != null) {
                if (typeof object.read_dir !== "object")
                    throw TypeError(".hbb.FileAction.read_dir: object expected");
                message.read_dir = $root.hbb.ReadDir.fromObject(object.read_dir, long + 1);
            }
            if (object.send != null) {
                if (typeof object.send !== "object")
                    throw TypeError(".hbb.FileAction.send: object expected");
                message.send = $root.hbb.FileTransferSendRequest.fromObject(object.send, long + 1);
            }
            if (object.receive != null) {
                if (typeof object.receive !== "object")
                    throw TypeError(".hbb.FileAction.receive: object expected");
                message.receive = $root.hbb.FileTransferReceiveRequest.fromObject(object.receive, long + 1);
            }
            if (object.create != null) {
                if (typeof object.create !== "object")
                    throw TypeError(".hbb.FileAction.create: object expected");
                message.create = $root.hbb.FileDirCreate.fromObject(object.create, long + 1);
            }
            if (object.remove_dir != null) {
                if (typeof object.remove_dir !== "object")
                    throw TypeError(".hbb.FileAction.remove_dir: object expected");
                message.remove_dir = $root.hbb.FileRemoveDir.fromObject(object.remove_dir, long + 1);
            }
            if (object.remove_file != null) {
                if (typeof object.remove_file !== "object")
                    throw TypeError(".hbb.FileAction.remove_file: object expected");
                message.remove_file = $root.hbb.FileRemoveFile.fromObject(object.remove_file, long + 1);
            }
            if (object.all_files != null) {
                if (typeof object.all_files !== "object")
                    throw TypeError(".hbb.FileAction.all_files: object expected");
                message.all_files = $root.hbb.ReadAllFiles.fromObject(object.all_files, long + 1);
            }
            if (object.cancel != null) {
                if (typeof object.cancel !== "object")
                    throw TypeError(".hbb.FileAction.cancel: object expected");
                message.cancel = $root.hbb.FileTransferCancel.fromObject(object.cancel, long + 1);
            }
            if (object.send_confirm != null) {
                if (typeof object.send_confirm !== "object")
                    throw TypeError(".hbb.FileAction.send_confirm: object expected");
                message.send_confirm = $root.hbb.FileTransferSendConfirmRequest.fromObject(object.send_confirm, long + 1);
            }
            if (object.rename != null) {
                if (typeof object.rename !== "object")
                    throw TypeError(".hbb.FileAction.rename: object expected");
                message.rename = $root.hbb.FileRename.fromObject(object.rename, long + 1);
            }
            if (object.read_empty_dirs != null) {
                if (typeof object.read_empty_dirs !== "object")
                    throw TypeError(".hbb.FileAction.read_empty_dirs: object expected");
                message.read_empty_dirs = $root.hbb.ReadEmptyDirs.fromObject(object.read_empty_dirs, long + 1);
            }
            return message;
        };

        /**
         * Creates a plain object from a FileAction message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.FileAction
         * @static
         * @param {hbb.FileAction} message FileAction
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        FileAction.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (message.read_dir != null && message.hasOwnProperty("read_dir")) {
                object.read_dir = $root.hbb.ReadDir.toObject(message.read_dir, options);
                if (options.oneofs)
                    object.union = "read_dir";
            }
            if (message.send != null && message.hasOwnProperty("send")) {
                object.send = $root.hbb.FileTransferSendRequest.toObject(message.send, options);
                if (options.oneofs)
                    object.union = "send";
            }
            if (message.receive != null && message.hasOwnProperty("receive")) {
                object.receive = $root.hbb.FileTransferReceiveRequest.toObject(message.receive, options);
                if (options.oneofs)
                    object.union = "receive";
            }
            if (message.create != null && message.hasOwnProperty("create")) {
                object.create = $root.hbb.FileDirCreate.toObject(message.create, options);
                if (options.oneofs)
                    object.union = "create";
            }
            if (message.remove_dir != null && message.hasOwnProperty("remove_dir")) {
                object.remove_dir = $root.hbb.FileRemoveDir.toObject(message.remove_dir, options);
                if (options.oneofs)
                    object.union = "remove_dir";
            }
            if (message.remove_file != null && message.hasOwnProperty("remove_file")) {
                object.remove_file = $root.hbb.FileRemoveFile.toObject(message.remove_file, options);
                if (options.oneofs)
                    object.union = "remove_file";
            }
            if (message.all_files != null && message.hasOwnProperty("all_files")) {
                object.all_files = $root.hbb.ReadAllFiles.toObject(message.all_files, options);
                if (options.oneofs)
                    object.union = "all_files";
            }
            if (message.cancel != null && message.hasOwnProperty("cancel")) {
                object.cancel = $root.hbb.FileTransferCancel.toObject(message.cancel, options);
                if (options.oneofs)
                    object.union = "cancel";
            }
            if (message.send_confirm != null && message.hasOwnProperty("send_confirm")) {
                object.send_confirm = $root.hbb.FileTransferSendConfirmRequest.toObject(message.send_confirm, options);
                if (options.oneofs)
                    object.union = "send_confirm";
            }
            if (message.rename != null && message.hasOwnProperty("rename")) {
                object.rename = $root.hbb.FileRename.toObject(message.rename, options);
                if (options.oneofs)
                    object.union = "rename";
            }
            if (message.read_empty_dirs != null && message.hasOwnProperty("read_empty_dirs")) {
                object.read_empty_dirs = $root.hbb.ReadEmptyDirs.toObject(message.read_empty_dirs, options);
                if (options.oneofs)
                    object.union = "read_empty_dirs";
            }
            return object;
        };

        /**
         * Converts this FileAction to JSON.
         * @function toJSON
         * @memberof hbb.FileAction
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        FileAction.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for FileAction
         * @function getTypeUrl
         * @memberof hbb.FileAction
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        FileAction.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.FileAction";
        };

        return FileAction;
    })();

    hbb.FileTransferCancel = (function() {

        /**
         * Properties of a FileTransferCancel.
         * @memberof hbb
         * @interface IFileTransferCancel
         * @property {number|null} [id] FileTransferCancel id
         */

        /**
         * Constructs a new FileTransferCancel.
         * @memberof hbb
         * @classdesc Represents a FileTransferCancel.
         * @implements IFileTransferCancel
         * @constructor
         * @param {hbb.IFileTransferCancel=} [properties] Properties to set
         */
        function FileTransferCancel(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * FileTransferCancel id.
         * @member {number} id
         * @memberof hbb.FileTransferCancel
         * @instance
         */
        FileTransferCancel.prototype.id = 0;

        /**
         * Creates a new FileTransferCancel instance using the specified properties.
         * @function create
         * @memberof hbb.FileTransferCancel
         * @static
         * @param {hbb.IFileTransferCancel=} [properties] Properties to set
         * @returns {hbb.FileTransferCancel} FileTransferCancel instance
         */
        FileTransferCancel.create = function create(properties) {
            return new FileTransferCancel(properties);
        };

        /**
         * Encodes the specified FileTransferCancel message. Does not implicitly {@link hbb.FileTransferCancel.verify|verify} messages.
         * @function encode
         * @memberof hbb.FileTransferCancel
         * @static
         * @param {hbb.IFileTransferCancel} message FileTransferCancel message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FileTransferCancel.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.id != null && Object.hasOwnProperty.call(message, "id"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.id);
            return writer;
        };

        /**
         * Encodes the specified FileTransferCancel message, length delimited. Does not implicitly {@link hbb.FileTransferCancel.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.FileTransferCancel
         * @static
         * @param {hbb.IFileTransferCancel} message FileTransferCancel message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FileTransferCancel.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a FileTransferCancel message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.FileTransferCancel
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.FileTransferCancel} FileTransferCancel
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FileTransferCancel.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.FileTransferCancel();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.id = reader.int32();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a FileTransferCancel message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.FileTransferCancel
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.FileTransferCancel} FileTransferCancel
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FileTransferCancel.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a FileTransferCancel message.
         * @function verify
         * @memberof hbb.FileTransferCancel
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        FileTransferCancel.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.id != null && message.hasOwnProperty("id"))
                if (!$util.isInteger(message.id))
                    return "id: integer expected";
            return null;
        };

        /**
         * Creates a FileTransferCancel message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.FileTransferCancel
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.FileTransferCancel} FileTransferCancel
         */
        FileTransferCancel.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.FileTransferCancel)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.FileTransferCancel();
            if (object.id != null)
                message.id = object.id | 0;
            return message;
        };

        /**
         * Creates a plain object from a FileTransferCancel message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.FileTransferCancel
         * @static
         * @param {hbb.FileTransferCancel} message FileTransferCancel
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        FileTransferCancel.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults)
                object.id = 0;
            if (message.id != null && message.hasOwnProperty("id"))
                object.id = message.id;
            return object;
        };

        /**
         * Converts this FileTransferCancel to JSON.
         * @function toJSON
         * @memberof hbb.FileTransferCancel
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        FileTransferCancel.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for FileTransferCancel
         * @function getTypeUrl
         * @memberof hbb.FileTransferCancel
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        FileTransferCancel.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.FileTransferCancel";
        };

        return FileTransferCancel;
    })();

    hbb.FileResponse = (function() {

        /**
         * Properties of a FileResponse.
         * @memberof hbb
         * @interface IFileResponse
         * @property {hbb.IFileDirectory|null} [dir] FileResponse dir
         * @property {hbb.IFileTransferBlock|null} [block] FileResponse block
         * @property {hbb.IFileTransferError|null} [error] FileResponse error
         * @property {hbb.IFileTransferDone|null} [done] FileResponse done
         * @property {hbb.IFileTransferDigest|null} [digest] FileResponse digest
         * @property {hbb.IReadEmptyDirsResponse|null} [empty_dirs] FileResponse empty_dirs
         */

        /**
         * Constructs a new FileResponse.
         * @memberof hbb
         * @classdesc Represents a FileResponse.
         * @implements IFileResponse
         * @constructor
         * @param {hbb.IFileResponse=} [properties] Properties to set
         */
        function FileResponse(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * FileResponse dir.
         * @member {hbb.IFileDirectory|null|undefined} dir
         * @memberof hbb.FileResponse
         * @instance
         */
        FileResponse.prototype.dir = null;

        /**
         * FileResponse block.
         * @member {hbb.IFileTransferBlock|null|undefined} block
         * @memberof hbb.FileResponse
         * @instance
         */
        FileResponse.prototype.block = null;

        /**
         * FileResponse error.
         * @member {hbb.IFileTransferError|null|undefined} error
         * @memberof hbb.FileResponse
         * @instance
         */
        FileResponse.prototype.error = null;

        /**
         * FileResponse done.
         * @member {hbb.IFileTransferDone|null|undefined} done
         * @memberof hbb.FileResponse
         * @instance
         */
        FileResponse.prototype.done = null;

        /**
         * FileResponse digest.
         * @member {hbb.IFileTransferDigest|null|undefined} digest
         * @memberof hbb.FileResponse
         * @instance
         */
        FileResponse.prototype.digest = null;

        /**
         * FileResponse empty_dirs.
         * @member {hbb.IReadEmptyDirsResponse|null|undefined} empty_dirs
         * @memberof hbb.FileResponse
         * @instance
         */
        FileResponse.prototype.empty_dirs = null;

        // OneOf field names bound to virtual getters and setters
        let $oneOfFields;

        /**
         * FileResponse union.
         * @member {"dir"|"block"|"error"|"done"|"digest"|"empty_dirs"|undefined} union
         * @memberof hbb.FileResponse
         * @instance
         */
        Object.defineProperty(FileResponse.prototype, "union", {
            get: $util.oneOfGetter($oneOfFields = ["dir", "block", "error", "done", "digest", "empty_dirs"]),
            set: $util.oneOfSetter($oneOfFields)
        });

        /**
         * Creates a new FileResponse instance using the specified properties.
         * @function create
         * @memberof hbb.FileResponse
         * @static
         * @param {hbb.IFileResponse=} [properties] Properties to set
         * @returns {hbb.FileResponse} FileResponse instance
         */
        FileResponse.create = function create(properties) {
            return new FileResponse(properties);
        };

        /**
         * Encodes the specified FileResponse message. Does not implicitly {@link hbb.FileResponse.verify|verify} messages.
         * @function encode
         * @memberof hbb.FileResponse
         * @static
         * @param {hbb.IFileResponse} message FileResponse message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FileResponse.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.dir != null && Object.hasOwnProperty.call(message, "dir"))
                $root.hbb.FileDirectory.encode(message.dir, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.block != null && Object.hasOwnProperty.call(message, "block"))
                $root.hbb.FileTransferBlock.encode(message.block, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            if (message.error != null && Object.hasOwnProperty.call(message, "error"))
                $root.hbb.FileTransferError.encode(message.error, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
            if (message.done != null && Object.hasOwnProperty.call(message, "done"))
                $root.hbb.FileTransferDone.encode(message.done, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim();
            if (message.digest != null && Object.hasOwnProperty.call(message, "digest"))
                $root.hbb.FileTransferDigest.encode(message.digest, writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim();
            if (message.empty_dirs != null && Object.hasOwnProperty.call(message, "empty_dirs"))
                $root.hbb.ReadEmptyDirsResponse.encode(message.empty_dirs, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified FileResponse message, length delimited. Does not implicitly {@link hbb.FileResponse.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.FileResponse
         * @static
         * @param {hbb.IFileResponse} message FileResponse message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FileResponse.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a FileResponse message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.FileResponse
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.FileResponse} FileResponse
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FileResponse.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.FileResponse();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.dir = $root.hbb.FileDirectory.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 2: {
                        message.block = $root.hbb.FileTransferBlock.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 3: {
                        message.error = $root.hbb.FileTransferError.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 4: {
                        message.done = $root.hbb.FileTransferDone.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 5: {
                        message.digest = $root.hbb.FileTransferDigest.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 6: {
                        message.empty_dirs = $root.hbb.ReadEmptyDirsResponse.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a FileResponse message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.FileResponse
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.FileResponse} FileResponse
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FileResponse.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a FileResponse message.
         * @function verify
         * @memberof hbb.FileResponse
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        FileResponse.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            let properties = {};
            if (message.dir != null && message.hasOwnProperty("dir")) {
                properties.union = 1;
                {
                    let error = $root.hbb.FileDirectory.verify(message.dir, long + 1);
                    if (error)
                        return "dir." + error;
                }
            }
            if (message.block != null && message.hasOwnProperty("block")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.FileTransferBlock.verify(message.block, long + 1);
                    if (error)
                        return "block." + error;
                }
            }
            if (message.error != null && message.hasOwnProperty("error")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.FileTransferError.verify(message.error, long + 1);
                    if (error)
                        return "error." + error;
                }
            }
            if (message.done != null && message.hasOwnProperty("done")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.FileTransferDone.verify(message.done, long + 1);
                    if (error)
                        return "done." + error;
                }
            }
            if (message.digest != null && message.hasOwnProperty("digest")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.FileTransferDigest.verify(message.digest, long + 1);
                    if (error)
                        return "digest." + error;
                }
            }
            if (message.empty_dirs != null && message.hasOwnProperty("empty_dirs")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.ReadEmptyDirsResponse.verify(message.empty_dirs, long + 1);
                    if (error)
                        return "empty_dirs." + error;
                }
            }
            return null;
        };

        /**
         * Creates a FileResponse message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.FileResponse
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.FileResponse} FileResponse
         */
        FileResponse.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.FileResponse)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.FileResponse();
            if (object.dir != null) {
                if (typeof object.dir !== "object")
                    throw TypeError(".hbb.FileResponse.dir: object expected");
                message.dir = $root.hbb.FileDirectory.fromObject(object.dir, long + 1);
            }
            if (object.block != null) {
                if (typeof object.block !== "object")
                    throw TypeError(".hbb.FileResponse.block: object expected");
                message.block = $root.hbb.FileTransferBlock.fromObject(object.block, long + 1);
            }
            if (object.error != null) {
                if (typeof object.error !== "object")
                    throw TypeError(".hbb.FileResponse.error: object expected");
                message.error = $root.hbb.FileTransferError.fromObject(object.error, long + 1);
            }
            if (object.done != null) {
                if (typeof object.done !== "object")
                    throw TypeError(".hbb.FileResponse.done: object expected");
                message.done = $root.hbb.FileTransferDone.fromObject(object.done, long + 1);
            }
            if (object.digest != null) {
                if (typeof object.digest !== "object")
                    throw TypeError(".hbb.FileResponse.digest: object expected");
                message.digest = $root.hbb.FileTransferDigest.fromObject(object.digest, long + 1);
            }
            if (object.empty_dirs != null) {
                if (typeof object.empty_dirs !== "object")
                    throw TypeError(".hbb.FileResponse.empty_dirs: object expected");
                message.empty_dirs = $root.hbb.ReadEmptyDirsResponse.fromObject(object.empty_dirs, long + 1);
            }
            return message;
        };

        /**
         * Creates a plain object from a FileResponse message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.FileResponse
         * @static
         * @param {hbb.FileResponse} message FileResponse
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        FileResponse.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (message.dir != null && message.hasOwnProperty("dir")) {
                object.dir = $root.hbb.FileDirectory.toObject(message.dir, options);
                if (options.oneofs)
                    object.union = "dir";
            }
            if (message.block != null && message.hasOwnProperty("block")) {
                object.block = $root.hbb.FileTransferBlock.toObject(message.block, options);
                if (options.oneofs)
                    object.union = "block";
            }
            if (message.error != null && message.hasOwnProperty("error")) {
                object.error = $root.hbb.FileTransferError.toObject(message.error, options);
                if (options.oneofs)
                    object.union = "error";
            }
            if (message.done != null && message.hasOwnProperty("done")) {
                object.done = $root.hbb.FileTransferDone.toObject(message.done, options);
                if (options.oneofs)
                    object.union = "done";
            }
            if (message.digest != null && message.hasOwnProperty("digest")) {
                object.digest = $root.hbb.FileTransferDigest.toObject(message.digest, options);
                if (options.oneofs)
                    object.union = "digest";
            }
            if (message.empty_dirs != null && message.hasOwnProperty("empty_dirs")) {
                object.empty_dirs = $root.hbb.ReadEmptyDirsResponse.toObject(message.empty_dirs, options);
                if (options.oneofs)
                    object.union = "empty_dirs";
            }
            return object;
        };

        /**
         * Converts this FileResponse to JSON.
         * @function toJSON
         * @memberof hbb.FileResponse
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        FileResponse.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for FileResponse
         * @function getTypeUrl
         * @memberof hbb.FileResponse
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        FileResponse.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.FileResponse";
        };

        return FileResponse;
    })();

    hbb.FileTransferDigest = (function() {

        /**
         * Properties of a FileTransferDigest.
         * @memberof hbb
         * @interface IFileTransferDigest
         * @property {number|null} [id] FileTransferDigest id
         * @property {number|null} [file_num] FileTransferDigest file_num
         * @property {number|Long|null} [last_modified] FileTransferDigest last_modified
         * @property {number|Long|null} [file_size] FileTransferDigest file_size
         * @property {boolean|null} [is_upload] FileTransferDigest is_upload
         * @property {boolean|null} [is_identical] FileTransferDigest is_identical
         */

        /**
         * Constructs a new FileTransferDigest.
         * @memberof hbb
         * @classdesc Represents a FileTransferDigest.
         * @implements IFileTransferDigest
         * @constructor
         * @param {hbb.IFileTransferDigest=} [properties] Properties to set
         */
        function FileTransferDigest(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * FileTransferDigest id.
         * @member {number} id
         * @memberof hbb.FileTransferDigest
         * @instance
         */
        FileTransferDigest.prototype.id = 0;

        /**
         * FileTransferDigest file_num.
         * @member {number} file_num
         * @memberof hbb.FileTransferDigest
         * @instance
         */
        FileTransferDigest.prototype.file_num = 0;

        /**
         * FileTransferDigest last_modified.
         * @member {number|Long} last_modified
         * @memberof hbb.FileTransferDigest
         * @instance
         */
        FileTransferDigest.prototype.last_modified = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * FileTransferDigest file_size.
         * @member {number|Long} file_size
         * @memberof hbb.FileTransferDigest
         * @instance
         */
        FileTransferDigest.prototype.file_size = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * FileTransferDigest is_upload.
         * @member {boolean} is_upload
         * @memberof hbb.FileTransferDigest
         * @instance
         */
        FileTransferDigest.prototype.is_upload = false;

        /**
         * FileTransferDigest is_identical.
         * @member {boolean} is_identical
         * @memberof hbb.FileTransferDigest
         * @instance
         */
        FileTransferDigest.prototype.is_identical = false;

        /**
         * Creates a new FileTransferDigest instance using the specified properties.
         * @function create
         * @memberof hbb.FileTransferDigest
         * @static
         * @param {hbb.IFileTransferDigest=} [properties] Properties to set
         * @returns {hbb.FileTransferDigest} FileTransferDigest instance
         */
        FileTransferDigest.create = function create(properties) {
            return new FileTransferDigest(properties);
        };

        /**
         * Encodes the specified FileTransferDigest message. Does not implicitly {@link hbb.FileTransferDigest.verify|verify} messages.
         * @function encode
         * @memberof hbb.FileTransferDigest
         * @static
         * @param {hbb.IFileTransferDigest} message FileTransferDigest message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FileTransferDigest.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.id != null && Object.hasOwnProperty.call(message, "id"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.id);
            if (message.file_num != null && Object.hasOwnProperty.call(message, "file_num"))
                writer.uint32(/* id 2, wireType 0 =*/16).sint32(message.file_num);
            if (message.last_modified != null && Object.hasOwnProperty.call(message, "last_modified"))
                writer.uint32(/* id 3, wireType 0 =*/24).uint64(message.last_modified);
            if (message.file_size != null && Object.hasOwnProperty.call(message, "file_size"))
                writer.uint32(/* id 4, wireType 0 =*/32).uint64(message.file_size);
            if (message.is_upload != null && Object.hasOwnProperty.call(message, "is_upload"))
                writer.uint32(/* id 5, wireType 0 =*/40).bool(message.is_upload);
            if (message.is_identical != null && Object.hasOwnProperty.call(message, "is_identical"))
                writer.uint32(/* id 6, wireType 0 =*/48).bool(message.is_identical);
            return writer;
        };

        /**
         * Encodes the specified FileTransferDigest message, length delimited. Does not implicitly {@link hbb.FileTransferDigest.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.FileTransferDigest
         * @static
         * @param {hbb.IFileTransferDigest} message FileTransferDigest message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FileTransferDigest.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a FileTransferDigest message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.FileTransferDigest
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.FileTransferDigest} FileTransferDigest
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FileTransferDigest.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.FileTransferDigest();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.id = reader.int32();
                        break;
                    }
                case 2: {
                        message.file_num = reader.sint32();
                        break;
                    }
                case 3: {
                        message.last_modified = reader.uint64();
                        break;
                    }
                case 4: {
                        message.file_size = reader.uint64();
                        break;
                    }
                case 5: {
                        message.is_upload = reader.bool();
                        break;
                    }
                case 6: {
                        message.is_identical = reader.bool();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a FileTransferDigest message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.FileTransferDigest
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.FileTransferDigest} FileTransferDigest
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FileTransferDigest.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a FileTransferDigest message.
         * @function verify
         * @memberof hbb.FileTransferDigest
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        FileTransferDigest.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.id != null && message.hasOwnProperty("id"))
                if (!$util.isInteger(message.id))
                    return "id: integer expected";
            if (message.file_num != null && message.hasOwnProperty("file_num"))
                if (!$util.isInteger(message.file_num))
                    return "file_num: integer expected";
            if (message.last_modified != null && message.hasOwnProperty("last_modified"))
                if (!$util.isInteger(message.last_modified) && !(message.last_modified && $util.isInteger(message.last_modified.low) && $util.isInteger(message.last_modified.high)))
                    return "last_modified: integer|Long expected";
            if (message.file_size != null && message.hasOwnProperty("file_size"))
                if (!$util.isInteger(message.file_size) && !(message.file_size && $util.isInteger(message.file_size.low) && $util.isInteger(message.file_size.high)))
                    return "file_size: integer|Long expected";
            if (message.is_upload != null && message.hasOwnProperty("is_upload"))
                if (typeof message.is_upload !== "boolean")
                    return "is_upload: boolean expected";
            if (message.is_identical != null && message.hasOwnProperty("is_identical"))
                if (typeof message.is_identical !== "boolean")
                    return "is_identical: boolean expected";
            return null;
        };

        /**
         * Creates a FileTransferDigest message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.FileTransferDigest
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.FileTransferDigest} FileTransferDigest
         */
        FileTransferDigest.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.FileTransferDigest)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.FileTransferDigest();
            if (object.id != null)
                message.id = object.id | 0;
            if (object.file_num != null)
                message.file_num = object.file_num | 0;
            if (object.last_modified != null)
                if ($util.Long)
                    (message.last_modified = $util.Long.fromValue(object.last_modified)).unsigned = true;
                else if (typeof object.last_modified === "string")
                    message.last_modified = parseInt(object.last_modified, 10);
                else if (typeof object.last_modified === "number")
                    message.last_modified = object.last_modified;
                else if (typeof object.last_modified === "object")
                    message.last_modified = new $util.LongBits(object.last_modified.low >>> 0, object.last_modified.high >>> 0).toNumber(true);
            if (object.file_size != null)
                if ($util.Long)
                    (message.file_size = $util.Long.fromValue(object.file_size)).unsigned = true;
                else if (typeof object.file_size === "string")
                    message.file_size = parseInt(object.file_size, 10);
                else if (typeof object.file_size === "number")
                    message.file_size = object.file_size;
                else if (typeof object.file_size === "object")
                    message.file_size = new $util.LongBits(object.file_size.low >>> 0, object.file_size.high >>> 0).toNumber(true);
            if (object.is_upload != null)
                message.is_upload = Boolean(object.is_upload);
            if (object.is_identical != null)
                message.is_identical = Boolean(object.is_identical);
            return message;
        };

        /**
         * Creates a plain object from a FileTransferDigest message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.FileTransferDigest
         * @static
         * @param {hbb.FileTransferDigest} message FileTransferDigest
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        FileTransferDigest.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.id = 0;
                object.file_num = 0;
                if ($util.Long) {
                    let long = new $util.Long(0, 0, true);
                    object.last_modified = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.last_modified = options.longs === String ? "0" : 0;
                if ($util.Long) {
                    let long = new $util.Long(0, 0, true);
                    object.file_size = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.file_size = options.longs === String ? "0" : 0;
                object.is_upload = false;
                object.is_identical = false;
            }
            if (message.id != null && message.hasOwnProperty("id"))
                object.id = message.id;
            if (message.file_num != null && message.hasOwnProperty("file_num"))
                object.file_num = message.file_num;
            if (message.last_modified != null && message.hasOwnProperty("last_modified"))
                if (typeof message.last_modified === "number")
                    object.last_modified = options.longs === String ? String(message.last_modified) : message.last_modified;
                else
                    object.last_modified = options.longs === String ? $util.Long.prototype.toString.call(message.last_modified) : options.longs === Number ? new $util.LongBits(message.last_modified.low >>> 0, message.last_modified.high >>> 0).toNumber(true) : message.last_modified;
            if (message.file_size != null && message.hasOwnProperty("file_size"))
                if (typeof message.file_size === "number")
                    object.file_size = options.longs === String ? String(message.file_size) : message.file_size;
                else
                    object.file_size = options.longs === String ? $util.Long.prototype.toString.call(message.file_size) : options.longs === Number ? new $util.LongBits(message.file_size.low >>> 0, message.file_size.high >>> 0).toNumber(true) : message.file_size;
            if (message.is_upload != null && message.hasOwnProperty("is_upload"))
                object.is_upload = message.is_upload;
            if (message.is_identical != null && message.hasOwnProperty("is_identical"))
                object.is_identical = message.is_identical;
            return object;
        };

        /**
         * Converts this FileTransferDigest to JSON.
         * @function toJSON
         * @memberof hbb.FileTransferDigest
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        FileTransferDigest.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for FileTransferDigest
         * @function getTypeUrl
         * @memberof hbb.FileTransferDigest
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        FileTransferDigest.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.FileTransferDigest";
        };

        return FileTransferDigest;
    })();

    hbb.FileTransferBlock = (function() {

        /**
         * Properties of a FileTransferBlock.
         * @memberof hbb
         * @interface IFileTransferBlock
         * @property {number|null} [id] FileTransferBlock id
         * @property {number|null} [file_num] FileTransferBlock file_num
         * @property {Uint8Array|null} [data] FileTransferBlock data
         * @property {boolean|null} [compressed] FileTransferBlock compressed
         * @property {number|null} [blk_id] FileTransferBlock blk_id
         */

        /**
         * Constructs a new FileTransferBlock.
         * @memberof hbb
         * @classdesc Represents a FileTransferBlock.
         * @implements IFileTransferBlock
         * @constructor
         * @param {hbb.IFileTransferBlock=} [properties] Properties to set
         */
        function FileTransferBlock(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * FileTransferBlock id.
         * @member {number} id
         * @memberof hbb.FileTransferBlock
         * @instance
         */
        FileTransferBlock.prototype.id = 0;

        /**
         * FileTransferBlock file_num.
         * @member {number} file_num
         * @memberof hbb.FileTransferBlock
         * @instance
         */
        FileTransferBlock.prototype.file_num = 0;

        /**
         * FileTransferBlock data.
         * @member {Uint8Array} data
         * @memberof hbb.FileTransferBlock
         * @instance
         */
        FileTransferBlock.prototype.data = $util.newBuffer([]);

        /**
         * FileTransferBlock compressed.
         * @member {boolean} compressed
         * @memberof hbb.FileTransferBlock
         * @instance
         */
        FileTransferBlock.prototype.compressed = false;

        /**
         * FileTransferBlock blk_id.
         * @member {number} blk_id
         * @memberof hbb.FileTransferBlock
         * @instance
         */
        FileTransferBlock.prototype.blk_id = 0;

        /**
         * Creates a new FileTransferBlock instance using the specified properties.
         * @function create
         * @memberof hbb.FileTransferBlock
         * @static
         * @param {hbb.IFileTransferBlock=} [properties] Properties to set
         * @returns {hbb.FileTransferBlock} FileTransferBlock instance
         */
        FileTransferBlock.create = function create(properties) {
            return new FileTransferBlock(properties);
        };

        /**
         * Encodes the specified FileTransferBlock message. Does not implicitly {@link hbb.FileTransferBlock.verify|verify} messages.
         * @function encode
         * @memberof hbb.FileTransferBlock
         * @static
         * @param {hbb.IFileTransferBlock} message FileTransferBlock message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FileTransferBlock.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.id != null && Object.hasOwnProperty.call(message, "id"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.id);
            if (message.file_num != null && Object.hasOwnProperty.call(message, "file_num"))
                writer.uint32(/* id 2, wireType 0 =*/16).sint32(message.file_num);
            if (message.data != null && Object.hasOwnProperty.call(message, "data"))
                writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.data);
            if (message.compressed != null && Object.hasOwnProperty.call(message, "compressed"))
                writer.uint32(/* id 4, wireType 0 =*/32).bool(message.compressed);
            if (message.blk_id != null && Object.hasOwnProperty.call(message, "blk_id"))
                writer.uint32(/* id 5, wireType 0 =*/40).uint32(message.blk_id);
            return writer;
        };

        /**
         * Encodes the specified FileTransferBlock message, length delimited. Does not implicitly {@link hbb.FileTransferBlock.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.FileTransferBlock
         * @static
         * @param {hbb.IFileTransferBlock} message FileTransferBlock message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FileTransferBlock.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a FileTransferBlock message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.FileTransferBlock
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.FileTransferBlock} FileTransferBlock
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FileTransferBlock.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.FileTransferBlock();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.id = reader.int32();
                        break;
                    }
                case 2: {
                        message.file_num = reader.sint32();
                        break;
                    }
                case 3: {
                        message.data = reader.bytes();
                        break;
                    }
                case 4: {
                        message.compressed = reader.bool();
                        break;
                    }
                case 5: {
                        message.blk_id = reader.uint32();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a FileTransferBlock message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.FileTransferBlock
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.FileTransferBlock} FileTransferBlock
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FileTransferBlock.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a FileTransferBlock message.
         * @function verify
         * @memberof hbb.FileTransferBlock
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        FileTransferBlock.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.id != null && message.hasOwnProperty("id"))
                if (!$util.isInteger(message.id))
                    return "id: integer expected";
            if (message.file_num != null && message.hasOwnProperty("file_num"))
                if (!$util.isInteger(message.file_num))
                    return "file_num: integer expected";
            if (message.data != null && message.hasOwnProperty("data"))
                if (!(message.data && typeof message.data.length === "number" || $util.isString(message.data)))
                    return "data: buffer expected";
            if (message.compressed != null && message.hasOwnProperty("compressed"))
                if (typeof message.compressed !== "boolean")
                    return "compressed: boolean expected";
            if (message.blk_id != null && message.hasOwnProperty("blk_id"))
                if (!$util.isInteger(message.blk_id))
                    return "blk_id: integer expected";
            return null;
        };

        /**
         * Creates a FileTransferBlock message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.FileTransferBlock
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.FileTransferBlock} FileTransferBlock
         */
        FileTransferBlock.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.FileTransferBlock)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.FileTransferBlock();
            if (object.id != null)
                message.id = object.id | 0;
            if (object.file_num != null)
                message.file_num = object.file_num | 0;
            if (object.data != null)
                if (typeof object.data === "string")
                    $util.base64.decode(object.data, message.data = $util.newBuffer($util.base64.length(object.data)), 0);
                else if (object.data.length >= 0)
                    message.data = object.data;
            if (object.compressed != null)
                message.compressed = Boolean(object.compressed);
            if (object.blk_id != null)
                message.blk_id = object.blk_id >>> 0;
            return message;
        };

        /**
         * Creates a plain object from a FileTransferBlock message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.FileTransferBlock
         * @static
         * @param {hbb.FileTransferBlock} message FileTransferBlock
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        FileTransferBlock.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.id = 0;
                object.file_num = 0;
                if (options.bytes === String)
                    object.data = "";
                else {
                    object.data = [];
                    if (options.bytes !== Array)
                        object.data = $util.newBuffer(object.data);
                }
                object.compressed = false;
                object.blk_id = 0;
            }
            if (message.id != null && message.hasOwnProperty("id"))
                object.id = message.id;
            if (message.file_num != null && message.hasOwnProperty("file_num"))
                object.file_num = message.file_num;
            if (message.data != null && message.hasOwnProperty("data"))
                object.data = options.bytes === String ? $util.base64.encode(message.data, 0, message.data.length) : options.bytes === Array ? Array.prototype.slice.call(message.data) : message.data;
            if (message.compressed != null && message.hasOwnProperty("compressed"))
                object.compressed = message.compressed;
            if (message.blk_id != null && message.hasOwnProperty("blk_id"))
                object.blk_id = message.blk_id;
            return object;
        };

        /**
         * Converts this FileTransferBlock to JSON.
         * @function toJSON
         * @memberof hbb.FileTransferBlock
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        FileTransferBlock.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for FileTransferBlock
         * @function getTypeUrl
         * @memberof hbb.FileTransferBlock
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        FileTransferBlock.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.FileTransferBlock";
        };

        return FileTransferBlock;
    })();

    hbb.FileTransferError = (function() {

        /**
         * Properties of a FileTransferError.
         * @memberof hbb
         * @interface IFileTransferError
         * @property {number|null} [id] FileTransferError id
         * @property {string|null} [error] FileTransferError error
         * @property {number|null} [file_num] FileTransferError file_num
         */

        /**
         * Constructs a new FileTransferError.
         * @memberof hbb
         * @classdesc Represents a FileTransferError.
         * @implements IFileTransferError
         * @constructor
         * @param {hbb.IFileTransferError=} [properties] Properties to set
         */
        function FileTransferError(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * FileTransferError id.
         * @member {number} id
         * @memberof hbb.FileTransferError
         * @instance
         */
        FileTransferError.prototype.id = 0;

        /**
         * FileTransferError error.
         * @member {string} error
         * @memberof hbb.FileTransferError
         * @instance
         */
        FileTransferError.prototype.error = "";

        /**
         * FileTransferError file_num.
         * @member {number} file_num
         * @memberof hbb.FileTransferError
         * @instance
         */
        FileTransferError.prototype.file_num = 0;

        /**
         * Creates a new FileTransferError instance using the specified properties.
         * @function create
         * @memberof hbb.FileTransferError
         * @static
         * @param {hbb.IFileTransferError=} [properties] Properties to set
         * @returns {hbb.FileTransferError} FileTransferError instance
         */
        FileTransferError.create = function create(properties) {
            return new FileTransferError(properties);
        };

        /**
         * Encodes the specified FileTransferError message. Does not implicitly {@link hbb.FileTransferError.verify|verify} messages.
         * @function encode
         * @memberof hbb.FileTransferError
         * @static
         * @param {hbb.IFileTransferError} message FileTransferError message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FileTransferError.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.id != null && Object.hasOwnProperty.call(message, "id"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.id);
            if (message.error != null && Object.hasOwnProperty.call(message, "error"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.error);
            if (message.file_num != null && Object.hasOwnProperty.call(message, "file_num"))
                writer.uint32(/* id 3, wireType 0 =*/24).sint32(message.file_num);
            return writer;
        };

        /**
         * Encodes the specified FileTransferError message, length delimited. Does not implicitly {@link hbb.FileTransferError.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.FileTransferError
         * @static
         * @param {hbb.IFileTransferError} message FileTransferError message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FileTransferError.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a FileTransferError message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.FileTransferError
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.FileTransferError} FileTransferError
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FileTransferError.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.FileTransferError();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.id = reader.int32();
                        break;
                    }
                case 2: {
                        message.error = reader.string();
                        break;
                    }
                case 3: {
                        message.file_num = reader.sint32();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a FileTransferError message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.FileTransferError
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.FileTransferError} FileTransferError
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FileTransferError.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a FileTransferError message.
         * @function verify
         * @memberof hbb.FileTransferError
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        FileTransferError.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.id != null && message.hasOwnProperty("id"))
                if (!$util.isInteger(message.id))
                    return "id: integer expected";
            if (message.error != null && message.hasOwnProperty("error"))
                if (!$util.isString(message.error))
                    return "error: string expected";
            if (message.file_num != null && message.hasOwnProperty("file_num"))
                if (!$util.isInteger(message.file_num))
                    return "file_num: integer expected";
            return null;
        };

        /**
         * Creates a FileTransferError message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.FileTransferError
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.FileTransferError} FileTransferError
         */
        FileTransferError.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.FileTransferError)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.FileTransferError();
            if (object.id != null)
                message.id = object.id | 0;
            if (object.error != null)
                message.error = String(object.error);
            if (object.file_num != null)
                message.file_num = object.file_num | 0;
            return message;
        };

        /**
         * Creates a plain object from a FileTransferError message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.FileTransferError
         * @static
         * @param {hbb.FileTransferError} message FileTransferError
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        FileTransferError.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.id = 0;
                object.error = "";
                object.file_num = 0;
            }
            if (message.id != null && message.hasOwnProperty("id"))
                object.id = message.id;
            if (message.error != null && message.hasOwnProperty("error"))
                object.error = message.error;
            if (message.file_num != null && message.hasOwnProperty("file_num"))
                object.file_num = message.file_num;
            return object;
        };

        /**
         * Converts this FileTransferError to JSON.
         * @function toJSON
         * @memberof hbb.FileTransferError
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        FileTransferError.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for FileTransferError
         * @function getTypeUrl
         * @memberof hbb.FileTransferError
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        FileTransferError.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.FileTransferError";
        };

        return FileTransferError;
    })();

    hbb.FileTransferSendRequest = (function() {

        /**
         * Properties of a FileTransferSendRequest.
         * @memberof hbb
         * @interface IFileTransferSendRequest
         * @property {number|null} [id] FileTransferSendRequest id
         * @property {string|null} [path] FileTransferSendRequest path
         * @property {boolean|null} [include_hidden] FileTransferSendRequest include_hidden
         * @property {number|null} [file_num] FileTransferSendRequest file_num
         */

        /**
         * Constructs a new FileTransferSendRequest.
         * @memberof hbb
         * @classdesc Represents a FileTransferSendRequest.
         * @implements IFileTransferSendRequest
         * @constructor
         * @param {hbb.IFileTransferSendRequest=} [properties] Properties to set
         */
        function FileTransferSendRequest(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * FileTransferSendRequest id.
         * @member {number} id
         * @memberof hbb.FileTransferSendRequest
         * @instance
         */
        FileTransferSendRequest.prototype.id = 0;

        /**
         * FileTransferSendRequest path.
         * @member {string} path
         * @memberof hbb.FileTransferSendRequest
         * @instance
         */
        FileTransferSendRequest.prototype.path = "";

        /**
         * FileTransferSendRequest include_hidden.
         * @member {boolean} include_hidden
         * @memberof hbb.FileTransferSendRequest
         * @instance
         */
        FileTransferSendRequest.prototype.include_hidden = false;

        /**
         * FileTransferSendRequest file_num.
         * @member {number} file_num
         * @memberof hbb.FileTransferSendRequest
         * @instance
         */
        FileTransferSendRequest.prototype.file_num = 0;

        /**
         * Creates a new FileTransferSendRequest instance using the specified properties.
         * @function create
         * @memberof hbb.FileTransferSendRequest
         * @static
         * @param {hbb.IFileTransferSendRequest=} [properties] Properties to set
         * @returns {hbb.FileTransferSendRequest} FileTransferSendRequest instance
         */
        FileTransferSendRequest.create = function create(properties) {
            return new FileTransferSendRequest(properties);
        };

        /**
         * Encodes the specified FileTransferSendRequest message. Does not implicitly {@link hbb.FileTransferSendRequest.verify|verify} messages.
         * @function encode
         * @memberof hbb.FileTransferSendRequest
         * @static
         * @param {hbb.IFileTransferSendRequest} message FileTransferSendRequest message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FileTransferSendRequest.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.id != null && Object.hasOwnProperty.call(message, "id"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.id);
            if (message.path != null && Object.hasOwnProperty.call(message, "path"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.path);
            if (message.include_hidden != null && Object.hasOwnProperty.call(message, "include_hidden"))
                writer.uint32(/* id 3, wireType 0 =*/24).bool(message.include_hidden);
            if (message.file_num != null && Object.hasOwnProperty.call(message, "file_num"))
                writer.uint32(/* id 4, wireType 0 =*/32).int32(message.file_num);
            return writer;
        };

        /**
         * Encodes the specified FileTransferSendRequest message, length delimited. Does not implicitly {@link hbb.FileTransferSendRequest.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.FileTransferSendRequest
         * @static
         * @param {hbb.IFileTransferSendRequest} message FileTransferSendRequest message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FileTransferSendRequest.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a FileTransferSendRequest message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.FileTransferSendRequest
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.FileTransferSendRequest} FileTransferSendRequest
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FileTransferSendRequest.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.FileTransferSendRequest();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.id = reader.int32();
                        break;
                    }
                case 2: {
                        message.path = reader.string();
                        break;
                    }
                case 3: {
                        message.include_hidden = reader.bool();
                        break;
                    }
                case 4: {
                        message.file_num = reader.int32();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a FileTransferSendRequest message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.FileTransferSendRequest
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.FileTransferSendRequest} FileTransferSendRequest
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FileTransferSendRequest.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a FileTransferSendRequest message.
         * @function verify
         * @memberof hbb.FileTransferSendRequest
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        FileTransferSendRequest.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.id != null && message.hasOwnProperty("id"))
                if (!$util.isInteger(message.id))
                    return "id: integer expected";
            if (message.path != null && message.hasOwnProperty("path"))
                if (!$util.isString(message.path))
                    return "path: string expected";
            if (message.include_hidden != null && message.hasOwnProperty("include_hidden"))
                if (typeof message.include_hidden !== "boolean")
                    return "include_hidden: boolean expected";
            if (message.file_num != null && message.hasOwnProperty("file_num"))
                if (!$util.isInteger(message.file_num))
                    return "file_num: integer expected";
            return null;
        };

        /**
         * Creates a FileTransferSendRequest message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.FileTransferSendRequest
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.FileTransferSendRequest} FileTransferSendRequest
         */
        FileTransferSendRequest.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.FileTransferSendRequest)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.FileTransferSendRequest();
            if (object.id != null)
                message.id = object.id | 0;
            if (object.path != null)
                message.path = String(object.path);
            if (object.include_hidden != null)
                message.include_hidden = Boolean(object.include_hidden);
            if (object.file_num != null)
                message.file_num = object.file_num | 0;
            return message;
        };

        /**
         * Creates a plain object from a FileTransferSendRequest message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.FileTransferSendRequest
         * @static
         * @param {hbb.FileTransferSendRequest} message FileTransferSendRequest
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        FileTransferSendRequest.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.id = 0;
                object.path = "";
                object.include_hidden = false;
                object.file_num = 0;
            }
            if (message.id != null && message.hasOwnProperty("id"))
                object.id = message.id;
            if (message.path != null && message.hasOwnProperty("path"))
                object.path = message.path;
            if (message.include_hidden != null && message.hasOwnProperty("include_hidden"))
                object.include_hidden = message.include_hidden;
            if (message.file_num != null && message.hasOwnProperty("file_num"))
                object.file_num = message.file_num;
            return object;
        };

        /**
         * Converts this FileTransferSendRequest to JSON.
         * @function toJSON
         * @memberof hbb.FileTransferSendRequest
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        FileTransferSendRequest.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for FileTransferSendRequest
         * @function getTypeUrl
         * @memberof hbb.FileTransferSendRequest
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        FileTransferSendRequest.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.FileTransferSendRequest";
        };

        return FileTransferSendRequest;
    })();

    hbb.FileTransferSendConfirmRequest = (function() {

        /**
         * Properties of a FileTransferSendConfirmRequest.
         * @memberof hbb
         * @interface IFileTransferSendConfirmRequest
         * @property {number|null} [id] FileTransferSendConfirmRequest id
         * @property {number|null} [file_num] FileTransferSendConfirmRequest file_num
         * @property {boolean|null} [skip] FileTransferSendConfirmRequest skip
         * @property {number|null} [offset_blk] FileTransferSendConfirmRequest offset_blk
         */

        /**
         * Constructs a new FileTransferSendConfirmRequest.
         * @memberof hbb
         * @classdesc Represents a FileTransferSendConfirmRequest.
         * @implements IFileTransferSendConfirmRequest
         * @constructor
         * @param {hbb.IFileTransferSendConfirmRequest=} [properties] Properties to set
         */
        function FileTransferSendConfirmRequest(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * FileTransferSendConfirmRequest id.
         * @member {number} id
         * @memberof hbb.FileTransferSendConfirmRequest
         * @instance
         */
        FileTransferSendConfirmRequest.prototype.id = 0;

        /**
         * FileTransferSendConfirmRequest file_num.
         * @member {number} file_num
         * @memberof hbb.FileTransferSendConfirmRequest
         * @instance
         */
        FileTransferSendConfirmRequest.prototype.file_num = 0;

        /**
         * FileTransferSendConfirmRequest skip.
         * @member {boolean|null|undefined} skip
         * @memberof hbb.FileTransferSendConfirmRequest
         * @instance
         */
        FileTransferSendConfirmRequest.prototype.skip = null;

        /**
         * FileTransferSendConfirmRequest offset_blk.
         * @member {number|null|undefined} offset_blk
         * @memberof hbb.FileTransferSendConfirmRequest
         * @instance
         */
        FileTransferSendConfirmRequest.prototype.offset_blk = null;

        // OneOf field names bound to virtual getters and setters
        let $oneOfFields;

        /**
         * FileTransferSendConfirmRequest union.
         * @member {"skip"|"offset_blk"|undefined} union
         * @memberof hbb.FileTransferSendConfirmRequest
         * @instance
         */
        Object.defineProperty(FileTransferSendConfirmRequest.prototype, "union", {
            get: $util.oneOfGetter($oneOfFields = ["skip", "offset_blk"]),
            set: $util.oneOfSetter($oneOfFields)
        });

        /**
         * Creates a new FileTransferSendConfirmRequest instance using the specified properties.
         * @function create
         * @memberof hbb.FileTransferSendConfirmRequest
         * @static
         * @param {hbb.IFileTransferSendConfirmRequest=} [properties] Properties to set
         * @returns {hbb.FileTransferSendConfirmRequest} FileTransferSendConfirmRequest instance
         */
        FileTransferSendConfirmRequest.create = function create(properties) {
            return new FileTransferSendConfirmRequest(properties);
        };

        /**
         * Encodes the specified FileTransferSendConfirmRequest message. Does not implicitly {@link hbb.FileTransferSendConfirmRequest.verify|verify} messages.
         * @function encode
         * @memberof hbb.FileTransferSendConfirmRequest
         * @static
         * @param {hbb.IFileTransferSendConfirmRequest} message FileTransferSendConfirmRequest message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FileTransferSendConfirmRequest.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.id != null && Object.hasOwnProperty.call(message, "id"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.id);
            if (message.file_num != null && Object.hasOwnProperty.call(message, "file_num"))
                writer.uint32(/* id 2, wireType 0 =*/16).sint32(message.file_num);
            if (message.skip != null && Object.hasOwnProperty.call(message, "skip"))
                writer.uint32(/* id 3, wireType 0 =*/24).bool(message.skip);
            if (message.offset_blk != null && Object.hasOwnProperty.call(message, "offset_blk"))
                writer.uint32(/* id 4, wireType 0 =*/32).uint32(message.offset_blk);
            return writer;
        };

        /**
         * Encodes the specified FileTransferSendConfirmRequest message, length delimited. Does not implicitly {@link hbb.FileTransferSendConfirmRequest.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.FileTransferSendConfirmRequest
         * @static
         * @param {hbb.IFileTransferSendConfirmRequest} message FileTransferSendConfirmRequest message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FileTransferSendConfirmRequest.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a FileTransferSendConfirmRequest message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.FileTransferSendConfirmRequest
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.FileTransferSendConfirmRequest} FileTransferSendConfirmRequest
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FileTransferSendConfirmRequest.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.FileTransferSendConfirmRequest();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.id = reader.int32();
                        break;
                    }
                case 2: {
                        message.file_num = reader.sint32();
                        break;
                    }
                case 3: {
                        message.skip = reader.bool();
                        break;
                    }
                case 4: {
                        message.offset_blk = reader.uint32();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a FileTransferSendConfirmRequest message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.FileTransferSendConfirmRequest
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.FileTransferSendConfirmRequest} FileTransferSendConfirmRequest
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FileTransferSendConfirmRequest.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a FileTransferSendConfirmRequest message.
         * @function verify
         * @memberof hbb.FileTransferSendConfirmRequest
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        FileTransferSendConfirmRequest.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            let properties = {};
            if (message.id != null && message.hasOwnProperty("id"))
                if (!$util.isInteger(message.id))
                    return "id: integer expected";
            if (message.file_num != null && message.hasOwnProperty("file_num"))
                if (!$util.isInteger(message.file_num))
                    return "file_num: integer expected";
            if (message.skip != null && message.hasOwnProperty("skip")) {
                properties.union = 1;
                if (typeof message.skip !== "boolean")
                    return "skip: boolean expected";
            }
            if (message.offset_blk != null && message.hasOwnProperty("offset_blk")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                if (!$util.isInteger(message.offset_blk))
                    return "offset_blk: integer expected";
            }
            return null;
        };

        /**
         * Creates a FileTransferSendConfirmRequest message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.FileTransferSendConfirmRequest
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.FileTransferSendConfirmRequest} FileTransferSendConfirmRequest
         */
        FileTransferSendConfirmRequest.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.FileTransferSendConfirmRequest)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.FileTransferSendConfirmRequest();
            if (object.id != null)
                message.id = object.id | 0;
            if (object.file_num != null)
                message.file_num = object.file_num | 0;
            if (object.skip != null)
                message.skip = Boolean(object.skip);
            if (object.offset_blk != null)
                message.offset_blk = object.offset_blk >>> 0;
            return message;
        };

        /**
         * Creates a plain object from a FileTransferSendConfirmRequest message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.FileTransferSendConfirmRequest
         * @static
         * @param {hbb.FileTransferSendConfirmRequest} message FileTransferSendConfirmRequest
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        FileTransferSendConfirmRequest.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.id = 0;
                object.file_num = 0;
            }
            if (message.id != null && message.hasOwnProperty("id"))
                object.id = message.id;
            if (message.file_num != null && message.hasOwnProperty("file_num"))
                object.file_num = message.file_num;
            if (message.skip != null && message.hasOwnProperty("skip")) {
                object.skip = message.skip;
                if (options.oneofs)
                    object.union = "skip";
            }
            if (message.offset_blk != null && message.hasOwnProperty("offset_blk")) {
                object.offset_blk = message.offset_blk;
                if (options.oneofs)
                    object.union = "offset_blk";
            }
            return object;
        };

        /**
         * Converts this FileTransferSendConfirmRequest to JSON.
         * @function toJSON
         * @memberof hbb.FileTransferSendConfirmRequest
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        FileTransferSendConfirmRequest.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for FileTransferSendConfirmRequest
         * @function getTypeUrl
         * @memberof hbb.FileTransferSendConfirmRequest
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        FileTransferSendConfirmRequest.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.FileTransferSendConfirmRequest";
        };

        return FileTransferSendConfirmRequest;
    })();

    hbb.FileTransferDone = (function() {

        /**
         * Properties of a FileTransferDone.
         * @memberof hbb
         * @interface IFileTransferDone
         * @property {number|null} [id] FileTransferDone id
         * @property {number|null} [file_num] FileTransferDone file_num
         */

        /**
         * Constructs a new FileTransferDone.
         * @memberof hbb
         * @classdesc Represents a FileTransferDone.
         * @implements IFileTransferDone
         * @constructor
         * @param {hbb.IFileTransferDone=} [properties] Properties to set
         */
        function FileTransferDone(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * FileTransferDone id.
         * @member {number} id
         * @memberof hbb.FileTransferDone
         * @instance
         */
        FileTransferDone.prototype.id = 0;

        /**
         * FileTransferDone file_num.
         * @member {number} file_num
         * @memberof hbb.FileTransferDone
         * @instance
         */
        FileTransferDone.prototype.file_num = 0;

        /**
         * Creates a new FileTransferDone instance using the specified properties.
         * @function create
         * @memberof hbb.FileTransferDone
         * @static
         * @param {hbb.IFileTransferDone=} [properties] Properties to set
         * @returns {hbb.FileTransferDone} FileTransferDone instance
         */
        FileTransferDone.create = function create(properties) {
            return new FileTransferDone(properties);
        };

        /**
         * Encodes the specified FileTransferDone message. Does not implicitly {@link hbb.FileTransferDone.verify|verify} messages.
         * @function encode
         * @memberof hbb.FileTransferDone
         * @static
         * @param {hbb.IFileTransferDone} message FileTransferDone message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FileTransferDone.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.id != null && Object.hasOwnProperty.call(message, "id"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.id);
            if (message.file_num != null && Object.hasOwnProperty.call(message, "file_num"))
                writer.uint32(/* id 2, wireType 0 =*/16).sint32(message.file_num);
            return writer;
        };

        /**
         * Encodes the specified FileTransferDone message, length delimited. Does not implicitly {@link hbb.FileTransferDone.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.FileTransferDone
         * @static
         * @param {hbb.IFileTransferDone} message FileTransferDone message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FileTransferDone.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a FileTransferDone message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.FileTransferDone
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.FileTransferDone} FileTransferDone
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FileTransferDone.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.FileTransferDone();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.id = reader.int32();
                        break;
                    }
                case 2: {
                        message.file_num = reader.sint32();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a FileTransferDone message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.FileTransferDone
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.FileTransferDone} FileTransferDone
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FileTransferDone.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a FileTransferDone message.
         * @function verify
         * @memberof hbb.FileTransferDone
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        FileTransferDone.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.id != null && message.hasOwnProperty("id"))
                if (!$util.isInteger(message.id))
                    return "id: integer expected";
            if (message.file_num != null && message.hasOwnProperty("file_num"))
                if (!$util.isInteger(message.file_num))
                    return "file_num: integer expected";
            return null;
        };

        /**
         * Creates a FileTransferDone message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.FileTransferDone
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.FileTransferDone} FileTransferDone
         */
        FileTransferDone.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.FileTransferDone)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.FileTransferDone();
            if (object.id != null)
                message.id = object.id | 0;
            if (object.file_num != null)
                message.file_num = object.file_num | 0;
            return message;
        };

        /**
         * Creates a plain object from a FileTransferDone message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.FileTransferDone
         * @static
         * @param {hbb.FileTransferDone} message FileTransferDone
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        FileTransferDone.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.id = 0;
                object.file_num = 0;
            }
            if (message.id != null && message.hasOwnProperty("id"))
                object.id = message.id;
            if (message.file_num != null && message.hasOwnProperty("file_num"))
                object.file_num = message.file_num;
            return object;
        };

        /**
         * Converts this FileTransferDone to JSON.
         * @function toJSON
         * @memberof hbb.FileTransferDone
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        FileTransferDone.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for FileTransferDone
         * @function getTypeUrl
         * @memberof hbb.FileTransferDone
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        FileTransferDone.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.FileTransferDone";
        };

        return FileTransferDone;
    })();

    hbb.FileTransferReceiveRequest = (function() {

        /**
         * Properties of a FileTransferReceiveRequest.
         * @memberof hbb
         * @interface IFileTransferReceiveRequest
         * @property {number|null} [id] FileTransferReceiveRequest id
         * @property {string|null} [path] FileTransferReceiveRequest path
         * @property {Array.<hbb.IFileEntry>|null} [files] FileTransferReceiveRequest files
         * @property {number|null} [file_num] FileTransferReceiveRequest file_num
         * @property {number|Long|null} [total_size] FileTransferReceiveRequest total_size
         */

        /**
         * Constructs a new FileTransferReceiveRequest.
         * @memberof hbb
         * @classdesc Represents a FileTransferReceiveRequest.
         * @implements IFileTransferReceiveRequest
         * @constructor
         * @param {hbb.IFileTransferReceiveRequest=} [properties] Properties to set
         */
        function FileTransferReceiveRequest(properties) {
            this.files = [];
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * FileTransferReceiveRequest id.
         * @member {number} id
         * @memberof hbb.FileTransferReceiveRequest
         * @instance
         */
        FileTransferReceiveRequest.prototype.id = 0;

        /**
         * FileTransferReceiveRequest path.
         * @member {string} path
         * @memberof hbb.FileTransferReceiveRequest
         * @instance
         */
        FileTransferReceiveRequest.prototype.path = "";

        /**
         * FileTransferReceiveRequest files.
         * @member {Array.<hbb.IFileEntry>} files
         * @memberof hbb.FileTransferReceiveRequest
         * @instance
         */
        FileTransferReceiveRequest.prototype.files = $util.emptyArray;

        /**
         * FileTransferReceiveRequest file_num.
         * @member {number} file_num
         * @memberof hbb.FileTransferReceiveRequest
         * @instance
         */
        FileTransferReceiveRequest.prototype.file_num = 0;

        /**
         * FileTransferReceiveRequest total_size.
         * @member {number|Long} total_size
         * @memberof hbb.FileTransferReceiveRequest
         * @instance
         */
        FileTransferReceiveRequest.prototype.total_size = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * Creates a new FileTransferReceiveRequest instance using the specified properties.
         * @function create
         * @memberof hbb.FileTransferReceiveRequest
         * @static
         * @param {hbb.IFileTransferReceiveRequest=} [properties] Properties to set
         * @returns {hbb.FileTransferReceiveRequest} FileTransferReceiveRequest instance
         */
        FileTransferReceiveRequest.create = function create(properties) {
            return new FileTransferReceiveRequest(properties);
        };

        /**
         * Encodes the specified FileTransferReceiveRequest message. Does not implicitly {@link hbb.FileTransferReceiveRequest.verify|verify} messages.
         * @function encode
         * @memberof hbb.FileTransferReceiveRequest
         * @static
         * @param {hbb.IFileTransferReceiveRequest} message FileTransferReceiveRequest message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FileTransferReceiveRequest.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.id != null && Object.hasOwnProperty.call(message, "id"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.id);
            if (message.path != null && Object.hasOwnProperty.call(message, "path"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.path);
            if (message.files != null && message.files.length)
                for (let i = 0; i < message.files.length; ++i)
                    $root.hbb.FileEntry.encode(message.files[i], writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
            if (message.file_num != null && Object.hasOwnProperty.call(message, "file_num"))
                writer.uint32(/* id 4, wireType 0 =*/32).int32(message.file_num);
            if (message.total_size != null && Object.hasOwnProperty.call(message, "total_size"))
                writer.uint32(/* id 5, wireType 0 =*/40).uint64(message.total_size);
            return writer;
        };

        /**
         * Encodes the specified FileTransferReceiveRequest message, length delimited. Does not implicitly {@link hbb.FileTransferReceiveRequest.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.FileTransferReceiveRequest
         * @static
         * @param {hbb.IFileTransferReceiveRequest} message FileTransferReceiveRequest message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FileTransferReceiveRequest.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a FileTransferReceiveRequest message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.FileTransferReceiveRequest
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.FileTransferReceiveRequest} FileTransferReceiveRequest
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FileTransferReceiveRequest.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.FileTransferReceiveRequest();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.id = reader.int32();
                        break;
                    }
                case 2: {
                        message.path = reader.string();
                        break;
                    }
                case 3: {
                        if (!(message.files && message.files.length))
                            message.files = [];
                        message.files.push($root.hbb.FileEntry.decode(reader, reader.uint32(), undefined, long + 1));
                        break;
                    }
                case 4: {
                        message.file_num = reader.int32();
                        break;
                    }
                case 5: {
                        message.total_size = reader.uint64();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a FileTransferReceiveRequest message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.FileTransferReceiveRequest
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.FileTransferReceiveRequest} FileTransferReceiveRequest
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FileTransferReceiveRequest.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a FileTransferReceiveRequest message.
         * @function verify
         * @memberof hbb.FileTransferReceiveRequest
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        FileTransferReceiveRequest.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.id != null && message.hasOwnProperty("id"))
                if (!$util.isInteger(message.id))
                    return "id: integer expected";
            if (message.path != null && message.hasOwnProperty("path"))
                if (!$util.isString(message.path))
                    return "path: string expected";
            if (message.files != null && message.hasOwnProperty("files")) {
                if (!Array.isArray(message.files))
                    return "files: array expected";
                for (let i = 0; i < message.files.length; ++i) {
                    let error = $root.hbb.FileEntry.verify(message.files[i], long + 1);
                    if (error)
                        return "files." + error;
                }
            }
            if (message.file_num != null && message.hasOwnProperty("file_num"))
                if (!$util.isInteger(message.file_num))
                    return "file_num: integer expected";
            if (message.total_size != null && message.hasOwnProperty("total_size"))
                if (!$util.isInteger(message.total_size) && !(message.total_size && $util.isInteger(message.total_size.low) && $util.isInteger(message.total_size.high)))
                    return "total_size: integer|Long expected";
            return null;
        };

        /**
         * Creates a FileTransferReceiveRequest message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.FileTransferReceiveRequest
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.FileTransferReceiveRequest} FileTransferReceiveRequest
         */
        FileTransferReceiveRequest.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.FileTransferReceiveRequest)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.FileTransferReceiveRequest();
            if (object.id != null)
                message.id = object.id | 0;
            if (object.path != null)
                message.path = String(object.path);
            if (object.files) {
                if (!Array.isArray(object.files))
                    throw TypeError(".hbb.FileTransferReceiveRequest.files: array expected");
                message.files = [];
                for (let i = 0; i < object.files.length; ++i) {
                    if (typeof object.files[i] !== "object")
                        throw TypeError(".hbb.FileTransferReceiveRequest.files: object expected");
                    message.files[i] = $root.hbb.FileEntry.fromObject(object.files[i], long + 1);
                }
            }
            if (object.file_num != null)
                message.file_num = object.file_num | 0;
            if (object.total_size != null)
                if ($util.Long)
                    (message.total_size = $util.Long.fromValue(object.total_size)).unsigned = true;
                else if (typeof object.total_size === "string")
                    message.total_size = parseInt(object.total_size, 10);
                else if (typeof object.total_size === "number")
                    message.total_size = object.total_size;
                else if (typeof object.total_size === "object")
                    message.total_size = new $util.LongBits(object.total_size.low >>> 0, object.total_size.high >>> 0).toNumber(true);
            return message;
        };

        /**
         * Creates a plain object from a FileTransferReceiveRequest message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.FileTransferReceiveRequest
         * @static
         * @param {hbb.FileTransferReceiveRequest} message FileTransferReceiveRequest
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        FileTransferReceiveRequest.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.arrays || options.defaults)
                object.files = [];
            if (options.defaults) {
                object.id = 0;
                object.path = "";
                object.file_num = 0;
                if ($util.Long) {
                    let long = new $util.Long(0, 0, true);
                    object.total_size = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.total_size = options.longs === String ? "0" : 0;
            }
            if (message.id != null && message.hasOwnProperty("id"))
                object.id = message.id;
            if (message.path != null && message.hasOwnProperty("path"))
                object.path = message.path;
            if (message.files && message.files.length) {
                object.files = [];
                for (let j = 0; j < message.files.length; ++j)
                    object.files[j] = $root.hbb.FileEntry.toObject(message.files[j], options);
            }
            if (message.file_num != null && message.hasOwnProperty("file_num"))
                object.file_num = message.file_num;
            if (message.total_size != null && message.hasOwnProperty("total_size"))
                if (typeof message.total_size === "number")
                    object.total_size = options.longs === String ? String(message.total_size) : message.total_size;
                else
                    object.total_size = options.longs === String ? $util.Long.prototype.toString.call(message.total_size) : options.longs === Number ? new $util.LongBits(message.total_size.low >>> 0, message.total_size.high >>> 0).toNumber(true) : message.total_size;
            return object;
        };

        /**
         * Converts this FileTransferReceiveRequest to JSON.
         * @function toJSON
         * @memberof hbb.FileTransferReceiveRequest
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        FileTransferReceiveRequest.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for FileTransferReceiveRequest
         * @function getTypeUrl
         * @memberof hbb.FileTransferReceiveRequest
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        FileTransferReceiveRequest.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.FileTransferReceiveRequest";
        };

        return FileTransferReceiveRequest;
    })();

    hbb.FileRemoveDir = (function() {

        /**
         * Properties of a FileRemoveDir.
         * @memberof hbb
         * @interface IFileRemoveDir
         * @property {number|null} [id] FileRemoveDir id
         * @property {string|null} [path] FileRemoveDir path
         * @property {boolean|null} [recursive] FileRemoveDir recursive
         */

        /**
         * Constructs a new FileRemoveDir.
         * @memberof hbb
         * @classdesc Represents a FileRemoveDir.
         * @implements IFileRemoveDir
         * @constructor
         * @param {hbb.IFileRemoveDir=} [properties] Properties to set
         */
        function FileRemoveDir(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * FileRemoveDir id.
         * @member {number} id
         * @memberof hbb.FileRemoveDir
         * @instance
         */
        FileRemoveDir.prototype.id = 0;

        /**
         * FileRemoveDir path.
         * @member {string} path
         * @memberof hbb.FileRemoveDir
         * @instance
         */
        FileRemoveDir.prototype.path = "";

        /**
         * FileRemoveDir recursive.
         * @member {boolean} recursive
         * @memberof hbb.FileRemoveDir
         * @instance
         */
        FileRemoveDir.prototype.recursive = false;

        /**
         * Creates a new FileRemoveDir instance using the specified properties.
         * @function create
         * @memberof hbb.FileRemoveDir
         * @static
         * @param {hbb.IFileRemoveDir=} [properties] Properties to set
         * @returns {hbb.FileRemoveDir} FileRemoveDir instance
         */
        FileRemoveDir.create = function create(properties) {
            return new FileRemoveDir(properties);
        };

        /**
         * Encodes the specified FileRemoveDir message. Does not implicitly {@link hbb.FileRemoveDir.verify|verify} messages.
         * @function encode
         * @memberof hbb.FileRemoveDir
         * @static
         * @param {hbb.IFileRemoveDir} message FileRemoveDir message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FileRemoveDir.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.id != null && Object.hasOwnProperty.call(message, "id"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.id);
            if (message.path != null && Object.hasOwnProperty.call(message, "path"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.path);
            if (message.recursive != null && Object.hasOwnProperty.call(message, "recursive"))
                writer.uint32(/* id 3, wireType 0 =*/24).bool(message.recursive);
            return writer;
        };

        /**
         * Encodes the specified FileRemoveDir message, length delimited. Does not implicitly {@link hbb.FileRemoveDir.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.FileRemoveDir
         * @static
         * @param {hbb.IFileRemoveDir} message FileRemoveDir message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FileRemoveDir.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a FileRemoveDir message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.FileRemoveDir
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.FileRemoveDir} FileRemoveDir
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FileRemoveDir.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.FileRemoveDir();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.id = reader.int32();
                        break;
                    }
                case 2: {
                        message.path = reader.string();
                        break;
                    }
                case 3: {
                        message.recursive = reader.bool();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a FileRemoveDir message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.FileRemoveDir
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.FileRemoveDir} FileRemoveDir
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FileRemoveDir.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a FileRemoveDir message.
         * @function verify
         * @memberof hbb.FileRemoveDir
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        FileRemoveDir.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.id != null && message.hasOwnProperty("id"))
                if (!$util.isInteger(message.id))
                    return "id: integer expected";
            if (message.path != null && message.hasOwnProperty("path"))
                if (!$util.isString(message.path))
                    return "path: string expected";
            if (message.recursive != null && message.hasOwnProperty("recursive"))
                if (typeof message.recursive !== "boolean")
                    return "recursive: boolean expected";
            return null;
        };

        /**
         * Creates a FileRemoveDir message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.FileRemoveDir
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.FileRemoveDir} FileRemoveDir
         */
        FileRemoveDir.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.FileRemoveDir)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.FileRemoveDir();
            if (object.id != null)
                message.id = object.id | 0;
            if (object.path != null)
                message.path = String(object.path);
            if (object.recursive != null)
                message.recursive = Boolean(object.recursive);
            return message;
        };

        /**
         * Creates a plain object from a FileRemoveDir message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.FileRemoveDir
         * @static
         * @param {hbb.FileRemoveDir} message FileRemoveDir
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        FileRemoveDir.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.id = 0;
                object.path = "";
                object.recursive = false;
            }
            if (message.id != null && message.hasOwnProperty("id"))
                object.id = message.id;
            if (message.path != null && message.hasOwnProperty("path"))
                object.path = message.path;
            if (message.recursive != null && message.hasOwnProperty("recursive"))
                object.recursive = message.recursive;
            return object;
        };

        /**
         * Converts this FileRemoveDir to JSON.
         * @function toJSON
         * @memberof hbb.FileRemoveDir
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        FileRemoveDir.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for FileRemoveDir
         * @function getTypeUrl
         * @memberof hbb.FileRemoveDir
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        FileRemoveDir.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.FileRemoveDir";
        };

        return FileRemoveDir;
    })();

    hbb.FileRemoveFile = (function() {

        /**
         * Properties of a FileRemoveFile.
         * @memberof hbb
         * @interface IFileRemoveFile
         * @property {number|null} [id] FileRemoveFile id
         * @property {string|null} [path] FileRemoveFile path
         * @property {number|null} [file_num] FileRemoveFile file_num
         */

        /**
         * Constructs a new FileRemoveFile.
         * @memberof hbb
         * @classdesc Represents a FileRemoveFile.
         * @implements IFileRemoveFile
         * @constructor
         * @param {hbb.IFileRemoveFile=} [properties] Properties to set
         */
        function FileRemoveFile(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * FileRemoveFile id.
         * @member {number} id
         * @memberof hbb.FileRemoveFile
         * @instance
         */
        FileRemoveFile.prototype.id = 0;

        /**
         * FileRemoveFile path.
         * @member {string} path
         * @memberof hbb.FileRemoveFile
         * @instance
         */
        FileRemoveFile.prototype.path = "";

        /**
         * FileRemoveFile file_num.
         * @member {number} file_num
         * @memberof hbb.FileRemoveFile
         * @instance
         */
        FileRemoveFile.prototype.file_num = 0;

        /**
         * Creates a new FileRemoveFile instance using the specified properties.
         * @function create
         * @memberof hbb.FileRemoveFile
         * @static
         * @param {hbb.IFileRemoveFile=} [properties] Properties to set
         * @returns {hbb.FileRemoveFile} FileRemoveFile instance
         */
        FileRemoveFile.create = function create(properties) {
            return new FileRemoveFile(properties);
        };

        /**
         * Encodes the specified FileRemoveFile message. Does not implicitly {@link hbb.FileRemoveFile.verify|verify} messages.
         * @function encode
         * @memberof hbb.FileRemoveFile
         * @static
         * @param {hbb.IFileRemoveFile} message FileRemoveFile message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FileRemoveFile.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.id != null && Object.hasOwnProperty.call(message, "id"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.id);
            if (message.path != null && Object.hasOwnProperty.call(message, "path"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.path);
            if (message.file_num != null && Object.hasOwnProperty.call(message, "file_num"))
                writer.uint32(/* id 3, wireType 0 =*/24).sint32(message.file_num);
            return writer;
        };

        /**
         * Encodes the specified FileRemoveFile message, length delimited. Does not implicitly {@link hbb.FileRemoveFile.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.FileRemoveFile
         * @static
         * @param {hbb.IFileRemoveFile} message FileRemoveFile message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FileRemoveFile.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a FileRemoveFile message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.FileRemoveFile
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.FileRemoveFile} FileRemoveFile
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FileRemoveFile.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.FileRemoveFile();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.id = reader.int32();
                        break;
                    }
                case 2: {
                        message.path = reader.string();
                        break;
                    }
                case 3: {
                        message.file_num = reader.sint32();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a FileRemoveFile message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.FileRemoveFile
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.FileRemoveFile} FileRemoveFile
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FileRemoveFile.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a FileRemoveFile message.
         * @function verify
         * @memberof hbb.FileRemoveFile
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        FileRemoveFile.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.id != null && message.hasOwnProperty("id"))
                if (!$util.isInteger(message.id))
                    return "id: integer expected";
            if (message.path != null && message.hasOwnProperty("path"))
                if (!$util.isString(message.path))
                    return "path: string expected";
            if (message.file_num != null && message.hasOwnProperty("file_num"))
                if (!$util.isInteger(message.file_num))
                    return "file_num: integer expected";
            return null;
        };

        /**
         * Creates a FileRemoveFile message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.FileRemoveFile
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.FileRemoveFile} FileRemoveFile
         */
        FileRemoveFile.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.FileRemoveFile)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.FileRemoveFile();
            if (object.id != null)
                message.id = object.id | 0;
            if (object.path != null)
                message.path = String(object.path);
            if (object.file_num != null)
                message.file_num = object.file_num | 0;
            return message;
        };

        /**
         * Creates a plain object from a FileRemoveFile message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.FileRemoveFile
         * @static
         * @param {hbb.FileRemoveFile} message FileRemoveFile
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        FileRemoveFile.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.id = 0;
                object.path = "";
                object.file_num = 0;
            }
            if (message.id != null && message.hasOwnProperty("id"))
                object.id = message.id;
            if (message.path != null && message.hasOwnProperty("path"))
                object.path = message.path;
            if (message.file_num != null && message.hasOwnProperty("file_num"))
                object.file_num = message.file_num;
            return object;
        };

        /**
         * Converts this FileRemoveFile to JSON.
         * @function toJSON
         * @memberof hbb.FileRemoveFile
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        FileRemoveFile.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for FileRemoveFile
         * @function getTypeUrl
         * @memberof hbb.FileRemoveFile
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        FileRemoveFile.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.FileRemoveFile";
        };

        return FileRemoveFile;
    })();

    hbb.FileDirCreate = (function() {

        /**
         * Properties of a FileDirCreate.
         * @memberof hbb
         * @interface IFileDirCreate
         * @property {number|null} [id] FileDirCreate id
         * @property {string|null} [path] FileDirCreate path
         */

        /**
         * Constructs a new FileDirCreate.
         * @memberof hbb
         * @classdesc Represents a FileDirCreate.
         * @implements IFileDirCreate
         * @constructor
         * @param {hbb.IFileDirCreate=} [properties] Properties to set
         */
        function FileDirCreate(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * FileDirCreate id.
         * @member {number} id
         * @memberof hbb.FileDirCreate
         * @instance
         */
        FileDirCreate.prototype.id = 0;

        /**
         * FileDirCreate path.
         * @member {string} path
         * @memberof hbb.FileDirCreate
         * @instance
         */
        FileDirCreate.prototype.path = "";

        /**
         * Creates a new FileDirCreate instance using the specified properties.
         * @function create
         * @memberof hbb.FileDirCreate
         * @static
         * @param {hbb.IFileDirCreate=} [properties] Properties to set
         * @returns {hbb.FileDirCreate} FileDirCreate instance
         */
        FileDirCreate.create = function create(properties) {
            return new FileDirCreate(properties);
        };

        /**
         * Encodes the specified FileDirCreate message. Does not implicitly {@link hbb.FileDirCreate.verify|verify} messages.
         * @function encode
         * @memberof hbb.FileDirCreate
         * @static
         * @param {hbb.IFileDirCreate} message FileDirCreate message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FileDirCreate.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.id != null && Object.hasOwnProperty.call(message, "id"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.id);
            if (message.path != null && Object.hasOwnProperty.call(message, "path"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.path);
            return writer;
        };

        /**
         * Encodes the specified FileDirCreate message, length delimited. Does not implicitly {@link hbb.FileDirCreate.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.FileDirCreate
         * @static
         * @param {hbb.IFileDirCreate} message FileDirCreate message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FileDirCreate.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a FileDirCreate message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.FileDirCreate
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.FileDirCreate} FileDirCreate
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FileDirCreate.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.FileDirCreate();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.id = reader.int32();
                        break;
                    }
                case 2: {
                        message.path = reader.string();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a FileDirCreate message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.FileDirCreate
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.FileDirCreate} FileDirCreate
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FileDirCreate.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a FileDirCreate message.
         * @function verify
         * @memberof hbb.FileDirCreate
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        FileDirCreate.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.id != null && message.hasOwnProperty("id"))
                if (!$util.isInteger(message.id))
                    return "id: integer expected";
            if (message.path != null && message.hasOwnProperty("path"))
                if (!$util.isString(message.path))
                    return "path: string expected";
            return null;
        };

        /**
         * Creates a FileDirCreate message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.FileDirCreate
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.FileDirCreate} FileDirCreate
         */
        FileDirCreate.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.FileDirCreate)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.FileDirCreate();
            if (object.id != null)
                message.id = object.id | 0;
            if (object.path != null)
                message.path = String(object.path);
            return message;
        };

        /**
         * Creates a plain object from a FileDirCreate message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.FileDirCreate
         * @static
         * @param {hbb.FileDirCreate} message FileDirCreate
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        FileDirCreate.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.id = 0;
                object.path = "";
            }
            if (message.id != null && message.hasOwnProperty("id"))
                object.id = message.id;
            if (message.path != null && message.hasOwnProperty("path"))
                object.path = message.path;
            return object;
        };

        /**
         * Converts this FileDirCreate to JSON.
         * @function toJSON
         * @memberof hbb.FileDirCreate
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        FileDirCreate.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for FileDirCreate
         * @function getTypeUrl
         * @memberof hbb.FileDirCreate
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        FileDirCreate.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.FileDirCreate";
        };

        return FileDirCreate;
    })();

    hbb.CliprdrMonitorReady = (function() {

        /**
         * Properties of a CliprdrMonitorReady.
         * @memberof hbb
         * @interface ICliprdrMonitorReady
         */

        /**
         * Constructs a new CliprdrMonitorReady.
         * @memberof hbb
         * @classdesc Represents a CliprdrMonitorReady.
         * @implements ICliprdrMonitorReady
         * @constructor
         * @param {hbb.ICliprdrMonitorReady=} [properties] Properties to set
         */
        function CliprdrMonitorReady(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * Creates a new CliprdrMonitorReady instance using the specified properties.
         * @function create
         * @memberof hbb.CliprdrMonitorReady
         * @static
         * @param {hbb.ICliprdrMonitorReady=} [properties] Properties to set
         * @returns {hbb.CliprdrMonitorReady} CliprdrMonitorReady instance
         */
        CliprdrMonitorReady.create = function create(properties) {
            return new CliprdrMonitorReady(properties);
        };

        /**
         * Encodes the specified CliprdrMonitorReady message. Does not implicitly {@link hbb.CliprdrMonitorReady.verify|verify} messages.
         * @function encode
         * @memberof hbb.CliprdrMonitorReady
         * @static
         * @param {hbb.ICliprdrMonitorReady} message CliprdrMonitorReady message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CliprdrMonitorReady.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            return writer;
        };

        /**
         * Encodes the specified CliprdrMonitorReady message, length delimited. Does not implicitly {@link hbb.CliprdrMonitorReady.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.CliprdrMonitorReady
         * @static
         * @param {hbb.ICliprdrMonitorReady} message CliprdrMonitorReady message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CliprdrMonitorReady.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a CliprdrMonitorReady message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.CliprdrMonitorReady
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.CliprdrMonitorReady} CliprdrMonitorReady
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CliprdrMonitorReady.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.CliprdrMonitorReady();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a CliprdrMonitorReady message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.CliprdrMonitorReady
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.CliprdrMonitorReady} CliprdrMonitorReady
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CliprdrMonitorReady.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a CliprdrMonitorReady message.
         * @function verify
         * @memberof hbb.CliprdrMonitorReady
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        CliprdrMonitorReady.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            return null;
        };

        /**
         * Creates a CliprdrMonitorReady message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.CliprdrMonitorReady
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.CliprdrMonitorReady} CliprdrMonitorReady
         */
        CliprdrMonitorReady.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.CliprdrMonitorReady)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            return new $root.hbb.CliprdrMonitorReady();
        };

        /**
         * Creates a plain object from a CliprdrMonitorReady message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.CliprdrMonitorReady
         * @static
         * @param {hbb.CliprdrMonitorReady} message CliprdrMonitorReady
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        CliprdrMonitorReady.toObject = function toObject() {
            return {};
        };

        /**
         * Converts this CliprdrMonitorReady to JSON.
         * @function toJSON
         * @memberof hbb.CliprdrMonitorReady
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        CliprdrMonitorReady.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for CliprdrMonitorReady
         * @function getTypeUrl
         * @memberof hbb.CliprdrMonitorReady
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        CliprdrMonitorReady.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.CliprdrMonitorReady";
        };

        return CliprdrMonitorReady;
    })();

    hbb.CliprdrFormat = (function() {

        /**
         * Properties of a CliprdrFormat.
         * @memberof hbb
         * @interface ICliprdrFormat
         * @property {number|null} [id] CliprdrFormat id
         * @property {string|null} [format] CliprdrFormat format
         */

        /**
         * Constructs a new CliprdrFormat.
         * @memberof hbb
         * @classdesc Represents a CliprdrFormat.
         * @implements ICliprdrFormat
         * @constructor
         * @param {hbb.ICliprdrFormat=} [properties] Properties to set
         */
        function CliprdrFormat(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * CliprdrFormat id.
         * @member {number} id
         * @memberof hbb.CliprdrFormat
         * @instance
         */
        CliprdrFormat.prototype.id = 0;

        /**
         * CliprdrFormat format.
         * @member {string} format
         * @memberof hbb.CliprdrFormat
         * @instance
         */
        CliprdrFormat.prototype.format = "";

        /**
         * Creates a new CliprdrFormat instance using the specified properties.
         * @function create
         * @memberof hbb.CliprdrFormat
         * @static
         * @param {hbb.ICliprdrFormat=} [properties] Properties to set
         * @returns {hbb.CliprdrFormat} CliprdrFormat instance
         */
        CliprdrFormat.create = function create(properties) {
            return new CliprdrFormat(properties);
        };

        /**
         * Encodes the specified CliprdrFormat message. Does not implicitly {@link hbb.CliprdrFormat.verify|verify} messages.
         * @function encode
         * @memberof hbb.CliprdrFormat
         * @static
         * @param {hbb.ICliprdrFormat} message CliprdrFormat message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CliprdrFormat.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.id != null && Object.hasOwnProperty.call(message, "id"))
                writer.uint32(/* id 2, wireType 0 =*/16).int32(message.id);
            if (message.format != null && Object.hasOwnProperty.call(message, "format"))
                writer.uint32(/* id 3, wireType 2 =*/26).string(message.format);
            return writer;
        };

        /**
         * Encodes the specified CliprdrFormat message, length delimited. Does not implicitly {@link hbb.CliprdrFormat.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.CliprdrFormat
         * @static
         * @param {hbb.ICliprdrFormat} message CliprdrFormat message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CliprdrFormat.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a CliprdrFormat message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.CliprdrFormat
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.CliprdrFormat} CliprdrFormat
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CliprdrFormat.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.CliprdrFormat();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 2: {
                        message.id = reader.int32();
                        break;
                    }
                case 3: {
                        message.format = reader.string();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a CliprdrFormat message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.CliprdrFormat
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.CliprdrFormat} CliprdrFormat
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CliprdrFormat.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a CliprdrFormat message.
         * @function verify
         * @memberof hbb.CliprdrFormat
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        CliprdrFormat.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.id != null && message.hasOwnProperty("id"))
                if (!$util.isInteger(message.id))
                    return "id: integer expected";
            if (message.format != null && message.hasOwnProperty("format"))
                if (!$util.isString(message.format))
                    return "format: string expected";
            return null;
        };

        /**
         * Creates a CliprdrFormat message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.CliprdrFormat
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.CliprdrFormat} CliprdrFormat
         */
        CliprdrFormat.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.CliprdrFormat)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.CliprdrFormat();
            if (object.id != null)
                message.id = object.id | 0;
            if (object.format != null)
                message.format = String(object.format);
            return message;
        };

        /**
         * Creates a plain object from a CliprdrFormat message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.CliprdrFormat
         * @static
         * @param {hbb.CliprdrFormat} message CliprdrFormat
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        CliprdrFormat.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.id = 0;
                object.format = "";
            }
            if (message.id != null && message.hasOwnProperty("id"))
                object.id = message.id;
            if (message.format != null && message.hasOwnProperty("format"))
                object.format = message.format;
            return object;
        };

        /**
         * Converts this CliprdrFormat to JSON.
         * @function toJSON
         * @memberof hbb.CliprdrFormat
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        CliprdrFormat.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for CliprdrFormat
         * @function getTypeUrl
         * @memberof hbb.CliprdrFormat
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        CliprdrFormat.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.CliprdrFormat";
        };

        return CliprdrFormat;
    })();

    hbb.CliprdrServerFormatList = (function() {

        /**
         * Properties of a CliprdrServerFormatList.
         * @memberof hbb
         * @interface ICliprdrServerFormatList
         * @property {Array.<hbb.ICliprdrFormat>|null} [formats] CliprdrServerFormatList formats
         */

        /**
         * Constructs a new CliprdrServerFormatList.
         * @memberof hbb
         * @classdesc Represents a CliprdrServerFormatList.
         * @implements ICliprdrServerFormatList
         * @constructor
         * @param {hbb.ICliprdrServerFormatList=} [properties] Properties to set
         */
        function CliprdrServerFormatList(properties) {
            this.formats = [];
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * CliprdrServerFormatList formats.
         * @member {Array.<hbb.ICliprdrFormat>} formats
         * @memberof hbb.CliprdrServerFormatList
         * @instance
         */
        CliprdrServerFormatList.prototype.formats = $util.emptyArray;

        /**
         * Creates a new CliprdrServerFormatList instance using the specified properties.
         * @function create
         * @memberof hbb.CliprdrServerFormatList
         * @static
         * @param {hbb.ICliprdrServerFormatList=} [properties] Properties to set
         * @returns {hbb.CliprdrServerFormatList} CliprdrServerFormatList instance
         */
        CliprdrServerFormatList.create = function create(properties) {
            return new CliprdrServerFormatList(properties);
        };

        /**
         * Encodes the specified CliprdrServerFormatList message. Does not implicitly {@link hbb.CliprdrServerFormatList.verify|verify} messages.
         * @function encode
         * @memberof hbb.CliprdrServerFormatList
         * @static
         * @param {hbb.ICliprdrServerFormatList} message CliprdrServerFormatList message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CliprdrServerFormatList.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.formats != null && message.formats.length)
                for (let i = 0; i < message.formats.length; ++i)
                    $root.hbb.CliprdrFormat.encode(message.formats[i], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified CliprdrServerFormatList message, length delimited. Does not implicitly {@link hbb.CliprdrServerFormatList.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.CliprdrServerFormatList
         * @static
         * @param {hbb.ICliprdrServerFormatList} message CliprdrServerFormatList message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CliprdrServerFormatList.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a CliprdrServerFormatList message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.CliprdrServerFormatList
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.CliprdrServerFormatList} CliprdrServerFormatList
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CliprdrServerFormatList.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.CliprdrServerFormatList();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 2: {
                        if (!(message.formats && message.formats.length))
                            message.formats = [];
                        message.formats.push($root.hbb.CliprdrFormat.decode(reader, reader.uint32(), undefined, long + 1));
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a CliprdrServerFormatList message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.CliprdrServerFormatList
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.CliprdrServerFormatList} CliprdrServerFormatList
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CliprdrServerFormatList.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a CliprdrServerFormatList message.
         * @function verify
         * @memberof hbb.CliprdrServerFormatList
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        CliprdrServerFormatList.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.formats != null && message.hasOwnProperty("formats")) {
                if (!Array.isArray(message.formats))
                    return "formats: array expected";
                for (let i = 0; i < message.formats.length; ++i) {
                    let error = $root.hbb.CliprdrFormat.verify(message.formats[i], long + 1);
                    if (error)
                        return "formats." + error;
                }
            }
            return null;
        };

        /**
         * Creates a CliprdrServerFormatList message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.CliprdrServerFormatList
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.CliprdrServerFormatList} CliprdrServerFormatList
         */
        CliprdrServerFormatList.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.CliprdrServerFormatList)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.CliprdrServerFormatList();
            if (object.formats) {
                if (!Array.isArray(object.formats))
                    throw TypeError(".hbb.CliprdrServerFormatList.formats: array expected");
                message.formats = [];
                for (let i = 0; i < object.formats.length; ++i) {
                    if (typeof object.formats[i] !== "object")
                        throw TypeError(".hbb.CliprdrServerFormatList.formats: object expected");
                    message.formats[i] = $root.hbb.CliprdrFormat.fromObject(object.formats[i], long + 1);
                }
            }
            return message;
        };

        /**
         * Creates a plain object from a CliprdrServerFormatList message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.CliprdrServerFormatList
         * @static
         * @param {hbb.CliprdrServerFormatList} message CliprdrServerFormatList
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        CliprdrServerFormatList.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.arrays || options.defaults)
                object.formats = [];
            if (message.formats && message.formats.length) {
                object.formats = [];
                for (let j = 0; j < message.formats.length; ++j)
                    object.formats[j] = $root.hbb.CliprdrFormat.toObject(message.formats[j], options);
            }
            return object;
        };

        /**
         * Converts this CliprdrServerFormatList to JSON.
         * @function toJSON
         * @memberof hbb.CliprdrServerFormatList
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        CliprdrServerFormatList.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for CliprdrServerFormatList
         * @function getTypeUrl
         * @memberof hbb.CliprdrServerFormatList
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        CliprdrServerFormatList.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.CliprdrServerFormatList";
        };

        return CliprdrServerFormatList;
    })();

    hbb.CliprdrServerFormatListResponse = (function() {

        /**
         * Properties of a CliprdrServerFormatListResponse.
         * @memberof hbb
         * @interface ICliprdrServerFormatListResponse
         * @property {number|null} [msg_flags] CliprdrServerFormatListResponse msg_flags
         */

        /**
         * Constructs a new CliprdrServerFormatListResponse.
         * @memberof hbb
         * @classdesc Represents a CliprdrServerFormatListResponse.
         * @implements ICliprdrServerFormatListResponse
         * @constructor
         * @param {hbb.ICliprdrServerFormatListResponse=} [properties] Properties to set
         */
        function CliprdrServerFormatListResponse(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * CliprdrServerFormatListResponse msg_flags.
         * @member {number} msg_flags
         * @memberof hbb.CliprdrServerFormatListResponse
         * @instance
         */
        CliprdrServerFormatListResponse.prototype.msg_flags = 0;

        /**
         * Creates a new CliprdrServerFormatListResponse instance using the specified properties.
         * @function create
         * @memberof hbb.CliprdrServerFormatListResponse
         * @static
         * @param {hbb.ICliprdrServerFormatListResponse=} [properties] Properties to set
         * @returns {hbb.CliprdrServerFormatListResponse} CliprdrServerFormatListResponse instance
         */
        CliprdrServerFormatListResponse.create = function create(properties) {
            return new CliprdrServerFormatListResponse(properties);
        };

        /**
         * Encodes the specified CliprdrServerFormatListResponse message. Does not implicitly {@link hbb.CliprdrServerFormatListResponse.verify|verify} messages.
         * @function encode
         * @memberof hbb.CliprdrServerFormatListResponse
         * @static
         * @param {hbb.ICliprdrServerFormatListResponse} message CliprdrServerFormatListResponse message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CliprdrServerFormatListResponse.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.msg_flags != null && Object.hasOwnProperty.call(message, "msg_flags"))
                writer.uint32(/* id 2, wireType 0 =*/16).int32(message.msg_flags);
            return writer;
        };

        /**
         * Encodes the specified CliprdrServerFormatListResponse message, length delimited. Does not implicitly {@link hbb.CliprdrServerFormatListResponse.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.CliprdrServerFormatListResponse
         * @static
         * @param {hbb.ICliprdrServerFormatListResponse} message CliprdrServerFormatListResponse message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CliprdrServerFormatListResponse.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a CliprdrServerFormatListResponse message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.CliprdrServerFormatListResponse
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.CliprdrServerFormatListResponse} CliprdrServerFormatListResponse
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CliprdrServerFormatListResponse.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.CliprdrServerFormatListResponse();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 2: {
                        message.msg_flags = reader.int32();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a CliprdrServerFormatListResponse message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.CliprdrServerFormatListResponse
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.CliprdrServerFormatListResponse} CliprdrServerFormatListResponse
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CliprdrServerFormatListResponse.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a CliprdrServerFormatListResponse message.
         * @function verify
         * @memberof hbb.CliprdrServerFormatListResponse
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        CliprdrServerFormatListResponse.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.msg_flags != null && message.hasOwnProperty("msg_flags"))
                if (!$util.isInteger(message.msg_flags))
                    return "msg_flags: integer expected";
            return null;
        };

        /**
         * Creates a CliprdrServerFormatListResponse message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.CliprdrServerFormatListResponse
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.CliprdrServerFormatListResponse} CliprdrServerFormatListResponse
         */
        CliprdrServerFormatListResponse.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.CliprdrServerFormatListResponse)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.CliprdrServerFormatListResponse();
            if (object.msg_flags != null)
                message.msg_flags = object.msg_flags | 0;
            return message;
        };

        /**
         * Creates a plain object from a CliprdrServerFormatListResponse message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.CliprdrServerFormatListResponse
         * @static
         * @param {hbb.CliprdrServerFormatListResponse} message CliprdrServerFormatListResponse
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        CliprdrServerFormatListResponse.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults)
                object.msg_flags = 0;
            if (message.msg_flags != null && message.hasOwnProperty("msg_flags"))
                object.msg_flags = message.msg_flags;
            return object;
        };

        /**
         * Converts this CliprdrServerFormatListResponse to JSON.
         * @function toJSON
         * @memberof hbb.CliprdrServerFormatListResponse
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        CliprdrServerFormatListResponse.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for CliprdrServerFormatListResponse
         * @function getTypeUrl
         * @memberof hbb.CliprdrServerFormatListResponse
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        CliprdrServerFormatListResponse.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.CliprdrServerFormatListResponse";
        };

        return CliprdrServerFormatListResponse;
    })();

    hbb.CliprdrServerFormatDataRequest = (function() {

        /**
         * Properties of a CliprdrServerFormatDataRequest.
         * @memberof hbb
         * @interface ICliprdrServerFormatDataRequest
         * @property {number|null} [requested_format_id] CliprdrServerFormatDataRequest requested_format_id
         */

        /**
         * Constructs a new CliprdrServerFormatDataRequest.
         * @memberof hbb
         * @classdesc Represents a CliprdrServerFormatDataRequest.
         * @implements ICliprdrServerFormatDataRequest
         * @constructor
         * @param {hbb.ICliprdrServerFormatDataRequest=} [properties] Properties to set
         */
        function CliprdrServerFormatDataRequest(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * CliprdrServerFormatDataRequest requested_format_id.
         * @member {number} requested_format_id
         * @memberof hbb.CliprdrServerFormatDataRequest
         * @instance
         */
        CliprdrServerFormatDataRequest.prototype.requested_format_id = 0;

        /**
         * Creates a new CliprdrServerFormatDataRequest instance using the specified properties.
         * @function create
         * @memberof hbb.CliprdrServerFormatDataRequest
         * @static
         * @param {hbb.ICliprdrServerFormatDataRequest=} [properties] Properties to set
         * @returns {hbb.CliprdrServerFormatDataRequest} CliprdrServerFormatDataRequest instance
         */
        CliprdrServerFormatDataRequest.create = function create(properties) {
            return new CliprdrServerFormatDataRequest(properties);
        };

        /**
         * Encodes the specified CliprdrServerFormatDataRequest message. Does not implicitly {@link hbb.CliprdrServerFormatDataRequest.verify|verify} messages.
         * @function encode
         * @memberof hbb.CliprdrServerFormatDataRequest
         * @static
         * @param {hbb.ICliprdrServerFormatDataRequest} message CliprdrServerFormatDataRequest message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CliprdrServerFormatDataRequest.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.requested_format_id != null && Object.hasOwnProperty.call(message, "requested_format_id"))
                writer.uint32(/* id 2, wireType 0 =*/16).int32(message.requested_format_id);
            return writer;
        };

        /**
         * Encodes the specified CliprdrServerFormatDataRequest message, length delimited. Does not implicitly {@link hbb.CliprdrServerFormatDataRequest.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.CliprdrServerFormatDataRequest
         * @static
         * @param {hbb.ICliprdrServerFormatDataRequest} message CliprdrServerFormatDataRequest message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CliprdrServerFormatDataRequest.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a CliprdrServerFormatDataRequest message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.CliprdrServerFormatDataRequest
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.CliprdrServerFormatDataRequest} CliprdrServerFormatDataRequest
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CliprdrServerFormatDataRequest.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.CliprdrServerFormatDataRequest();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 2: {
                        message.requested_format_id = reader.int32();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a CliprdrServerFormatDataRequest message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.CliprdrServerFormatDataRequest
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.CliprdrServerFormatDataRequest} CliprdrServerFormatDataRequest
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CliprdrServerFormatDataRequest.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a CliprdrServerFormatDataRequest message.
         * @function verify
         * @memberof hbb.CliprdrServerFormatDataRequest
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        CliprdrServerFormatDataRequest.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.requested_format_id != null && message.hasOwnProperty("requested_format_id"))
                if (!$util.isInteger(message.requested_format_id))
                    return "requested_format_id: integer expected";
            return null;
        };

        /**
         * Creates a CliprdrServerFormatDataRequest message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.CliprdrServerFormatDataRequest
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.CliprdrServerFormatDataRequest} CliprdrServerFormatDataRequest
         */
        CliprdrServerFormatDataRequest.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.CliprdrServerFormatDataRequest)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.CliprdrServerFormatDataRequest();
            if (object.requested_format_id != null)
                message.requested_format_id = object.requested_format_id | 0;
            return message;
        };

        /**
         * Creates a plain object from a CliprdrServerFormatDataRequest message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.CliprdrServerFormatDataRequest
         * @static
         * @param {hbb.CliprdrServerFormatDataRequest} message CliprdrServerFormatDataRequest
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        CliprdrServerFormatDataRequest.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults)
                object.requested_format_id = 0;
            if (message.requested_format_id != null && message.hasOwnProperty("requested_format_id"))
                object.requested_format_id = message.requested_format_id;
            return object;
        };

        /**
         * Converts this CliprdrServerFormatDataRequest to JSON.
         * @function toJSON
         * @memberof hbb.CliprdrServerFormatDataRequest
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        CliprdrServerFormatDataRequest.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for CliprdrServerFormatDataRequest
         * @function getTypeUrl
         * @memberof hbb.CliprdrServerFormatDataRequest
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        CliprdrServerFormatDataRequest.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.CliprdrServerFormatDataRequest";
        };

        return CliprdrServerFormatDataRequest;
    })();

    hbb.CliprdrServerFormatDataResponse = (function() {

        /**
         * Properties of a CliprdrServerFormatDataResponse.
         * @memberof hbb
         * @interface ICliprdrServerFormatDataResponse
         * @property {number|null} [msg_flags] CliprdrServerFormatDataResponse msg_flags
         * @property {Uint8Array|null} [format_data] CliprdrServerFormatDataResponse format_data
         */

        /**
         * Constructs a new CliprdrServerFormatDataResponse.
         * @memberof hbb
         * @classdesc Represents a CliprdrServerFormatDataResponse.
         * @implements ICliprdrServerFormatDataResponse
         * @constructor
         * @param {hbb.ICliprdrServerFormatDataResponse=} [properties] Properties to set
         */
        function CliprdrServerFormatDataResponse(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * CliprdrServerFormatDataResponse msg_flags.
         * @member {number} msg_flags
         * @memberof hbb.CliprdrServerFormatDataResponse
         * @instance
         */
        CliprdrServerFormatDataResponse.prototype.msg_flags = 0;

        /**
         * CliprdrServerFormatDataResponse format_data.
         * @member {Uint8Array} format_data
         * @memberof hbb.CliprdrServerFormatDataResponse
         * @instance
         */
        CliprdrServerFormatDataResponse.prototype.format_data = $util.newBuffer([]);

        /**
         * Creates a new CliprdrServerFormatDataResponse instance using the specified properties.
         * @function create
         * @memberof hbb.CliprdrServerFormatDataResponse
         * @static
         * @param {hbb.ICliprdrServerFormatDataResponse=} [properties] Properties to set
         * @returns {hbb.CliprdrServerFormatDataResponse} CliprdrServerFormatDataResponse instance
         */
        CliprdrServerFormatDataResponse.create = function create(properties) {
            return new CliprdrServerFormatDataResponse(properties);
        };

        /**
         * Encodes the specified CliprdrServerFormatDataResponse message. Does not implicitly {@link hbb.CliprdrServerFormatDataResponse.verify|verify} messages.
         * @function encode
         * @memberof hbb.CliprdrServerFormatDataResponse
         * @static
         * @param {hbb.ICliprdrServerFormatDataResponse} message CliprdrServerFormatDataResponse message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CliprdrServerFormatDataResponse.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.msg_flags != null && Object.hasOwnProperty.call(message, "msg_flags"))
                writer.uint32(/* id 2, wireType 0 =*/16).int32(message.msg_flags);
            if (message.format_data != null && Object.hasOwnProperty.call(message, "format_data"))
                writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.format_data);
            return writer;
        };

        /**
         * Encodes the specified CliprdrServerFormatDataResponse message, length delimited. Does not implicitly {@link hbb.CliprdrServerFormatDataResponse.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.CliprdrServerFormatDataResponse
         * @static
         * @param {hbb.ICliprdrServerFormatDataResponse} message CliprdrServerFormatDataResponse message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CliprdrServerFormatDataResponse.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a CliprdrServerFormatDataResponse message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.CliprdrServerFormatDataResponse
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.CliprdrServerFormatDataResponse} CliprdrServerFormatDataResponse
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CliprdrServerFormatDataResponse.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.CliprdrServerFormatDataResponse();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 2: {
                        message.msg_flags = reader.int32();
                        break;
                    }
                case 3: {
                        message.format_data = reader.bytes();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a CliprdrServerFormatDataResponse message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.CliprdrServerFormatDataResponse
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.CliprdrServerFormatDataResponse} CliprdrServerFormatDataResponse
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CliprdrServerFormatDataResponse.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a CliprdrServerFormatDataResponse message.
         * @function verify
         * @memberof hbb.CliprdrServerFormatDataResponse
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        CliprdrServerFormatDataResponse.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.msg_flags != null && message.hasOwnProperty("msg_flags"))
                if (!$util.isInteger(message.msg_flags))
                    return "msg_flags: integer expected";
            if (message.format_data != null && message.hasOwnProperty("format_data"))
                if (!(message.format_data && typeof message.format_data.length === "number" || $util.isString(message.format_data)))
                    return "format_data: buffer expected";
            return null;
        };

        /**
         * Creates a CliprdrServerFormatDataResponse message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.CliprdrServerFormatDataResponse
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.CliprdrServerFormatDataResponse} CliprdrServerFormatDataResponse
         */
        CliprdrServerFormatDataResponse.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.CliprdrServerFormatDataResponse)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.CliprdrServerFormatDataResponse();
            if (object.msg_flags != null)
                message.msg_flags = object.msg_flags | 0;
            if (object.format_data != null)
                if (typeof object.format_data === "string")
                    $util.base64.decode(object.format_data, message.format_data = $util.newBuffer($util.base64.length(object.format_data)), 0);
                else if (object.format_data.length >= 0)
                    message.format_data = object.format_data;
            return message;
        };

        /**
         * Creates a plain object from a CliprdrServerFormatDataResponse message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.CliprdrServerFormatDataResponse
         * @static
         * @param {hbb.CliprdrServerFormatDataResponse} message CliprdrServerFormatDataResponse
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        CliprdrServerFormatDataResponse.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.msg_flags = 0;
                if (options.bytes === String)
                    object.format_data = "";
                else {
                    object.format_data = [];
                    if (options.bytes !== Array)
                        object.format_data = $util.newBuffer(object.format_data);
                }
            }
            if (message.msg_flags != null && message.hasOwnProperty("msg_flags"))
                object.msg_flags = message.msg_flags;
            if (message.format_data != null && message.hasOwnProperty("format_data"))
                object.format_data = options.bytes === String ? $util.base64.encode(message.format_data, 0, message.format_data.length) : options.bytes === Array ? Array.prototype.slice.call(message.format_data) : message.format_data;
            return object;
        };

        /**
         * Converts this CliprdrServerFormatDataResponse to JSON.
         * @function toJSON
         * @memberof hbb.CliprdrServerFormatDataResponse
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        CliprdrServerFormatDataResponse.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for CliprdrServerFormatDataResponse
         * @function getTypeUrl
         * @memberof hbb.CliprdrServerFormatDataResponse
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        CliprdrServerFormatDataResponse.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.CliprdrServerFormatDataResponse";
        };

        return CliprdrServerFormatDataResponse;
    })();

    hbb.CliprdrFileContentsRequest = (function() {

        /**
         * Properties of a CliprdrFileContentsRequest.
         * @memberof hbb
         * @interface ICliprdrFileContentsRequest
         * @property {number|null} [stream_id] CliprdrFileContentsRequest stream_id
         * @property {number|null} [list_index] CliprdrFileContentsRequest list_index
         * @property {number|null} [dw_flags] CliprdrFileContentsRequest dw_flags
         * @property {number|null} [n_position_low] CliprdrFileContentsRequest n_position_low
         * @property {number|null} [n_position_high] CliprdrFileContentsRequest n_position_high
         * @property {number|null} [cb_requested] CliprdrFileContentsRequest cb_requested
         * @property {boolean|null} [have_clip_data_id] CliprdrFileContentsRequest have_clip_data_id
         * @property {number|null} [clip_data_id] CliprdrFileContentsRequest clip_data_id
         */

        /**
         * Constructs a new CliprdrFileContentsRequest.
         * @memberof hbb
         * @classdesc Represents a CliprdrFileContentsRequest.
         * @implements ICliprdrFileContentsRequest
         * @constructor
         * @param {hbb.ICliprdrFileContentsRequest=} [properties] Properties to set
         */
        function CliprdrFileContentsRequest(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * CliprdrFileContentsRequest stream_id.
         * @member {number} stream_id
         * @memberof hbb.CliprdrFileContentsRequest
         * @instance
         */
        CliprdrFileContentsRequest.prototype.stream_id = 0;

        /**
         * CliprdrFileContentsRequest list_index.
         * @member {number} list_index
         * @memberof hbb.CliprdrFileContentsRequest
         * @instance
         */
        CliprdrFileContentsRequest.prototype.list_index = 0;

        /**
         * CliprdrFileContentsRequest dw_flags.
         * @member {number} dw_flags
         * @memberof hbb.CliprdrFileContentsRequest
         * @instance
         */
        CliprdrFileContentsRequest.prototype.dw_flags = 0;

        /**
         * CliprdrFileContentsRequest n_position_low.
         * @member {number} n_position_low
         * @memberof hbb.CliprdrFileContentsRequest
         * @instance
         */
        CliprdrFileContentsRequest.prototype.n_position_low = 0;

        /**
         * CliprdrFileContentsRequest n_position_high.
         * @member {number} n_position_high
         * @memberof hbb.CliprdrFileContentsRequest
         * @instance
         */
        CliprdrFileContentsRequest.prototype.n_position_high = 0;

        /**
         * CliprdrFileContentsRequest cb_requested.
         * @member {number} cb_requested
         * @memberof hbb.CliprdrFileContentsRequest
         * @instance
         */
        CliprdrFileContentsRequest.prototype.cb_requested = 0;

        /**
         * CliprdrFileContentsRequest have_clip_data_id.
         * @member {boolean} have_clip_data_id
         * @memberof hbb.CliprdrFileContentsRequest
         * @instance
         */
        CliprdrFileContentsRequest.prototype.have_clip_data_id = false;

        /**
         * CliprdrFileContentsRequest clip_data_id.
         * @member {number} clip_data_id
         * @memberof hbb.CliprdrFileContentsRequest
         * @instance
         */
        CliprdrFileContentsRequest.prototype.clip_data_id = 0;

        /**
         * Creates a new CliprdrFileContentsRequest instance using the specified properties.
         * @function create
         * @memberof hbb.CliprdrFileContentsRequest
         * @static
         * @param {hbb.ICliprdrFileContentsRequest=} [properties] Properties to set
         * @returns {hbb.CliprdrFileContentsRequest} CliprdrFileContentsRequest instance
         */
        CliprdrFileContentsRequest.create = function create(properties) {
            return new CliprdrFileContentsRequest(properties);
        };

        /**
         * Encodes the specified CliprdrFileContentsRequest message. Does not implicitly {@link hbb.CliprdrFileContentsRequest.verify|verify} messages.
         * @function encode
         * @memberof hbb.CliprdrFileContentsRequest
         * @static
         * @param {hbb.ICliprdrFileContentsRequest} message CliprdrFileContentsRequest message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CliprdrFileContentsRequest.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.stream_id != null && Object.hasOwnProperty.call(message, "stream_id"))
                writer.uint32(/* id 2, wireType 0 =*/16).int32(message.stream_id);
            if (message.list_index != null && Object.hasOwnProperty.call(message, "list_index"))
                writer.uint32(/* id 3, wireType 0 =*/24).int32(message.list_index);
            if (message.dw_flags != null && Object.hasOwnProperty.call(message, "dw_flags"))
                writer.uint32(/* id 4, wireType 0 =*/32).int32(message.dw_flags);
            if (message.n_position_low != null && Object.hasOwnProperty.call(message, "n_position_low"))
                writer.uint32(/* id 5, wireType 0 =*/40).int32(message.n_position_low);
            if (message.n_position_high != null && Object.hasOwnProperty.call(message, "n_position_high"))
                writer.uint32(/* id 6, wireType 0 =*/48).int32(message.n_position_high);
            if (message.cb_requested != null && Object.hasOwnProperty.call(message, "cb_requested"))
                writer.uint32(/* id 7, wireType 0 =*/56).int32(message.cb_requested);
            if (message.have_clip_data_id != null && Object.hasOwnProperty.call(message, "have_clip_data_id"))
                writer.uint32(/* id 8, wireType 0 =*/64).bool(message.have_clip_data_id);
            if (message.clip_data_id != null && Object.hasOwnProperty.call(message, "clip_data_id"))
                writer.uint32(/* id 9, wireType 0 =*/72).int32(message.clip_data_id);
            return writer;
        };

        /**
         * Encodes the specified CliprdrFileContentsRequest message, length delimited. Does not implicitly {@link hbb.CliprdrFileContentsRequest.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.CliprdrFileContentsRequest
         * @static
         * @param {hbb.ICliprdrFileContentsRequest} message CliprdrFileContentsRequest message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CliprdrFileContentsRequest.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a CliprdrFileContentsRequest message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.CliprdrFileContentsRequest
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.CliprdrFileContentsRequest} CliprdrFileContentsRequest
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CliprdrFileContentsRequest.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.CliprdrFileContentsRequest();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 2: {
                        message.stream_id = reader.int32();
                        break;
                    }
                case 3: {
                        message.list_index = reader.int32();
                        break;
                    }
                case 4: {
                        message.dw_flags = reader.int32();
                        break;
                    }
                case 5: {
                        message.n_position_low = reader.int32();
                        break;
                    }
                case 6: {
                        message.n_position_high = reader.int32();
                        break;
                    }
                case 7: {
                        message.cb_requested = reader.int32();
                        break;
                    }
                case 8: {
                        message.have_clip_data_id = reader.bool();
                        break;
                    }
                case 9: {
                        message.clip_data_id = reader.int32();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a CliprdrFileContentsRequest message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.CliprdrFileContentsRequest
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.CliprdrFileContentsRequest} CliprdrFileContentsRequest
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CliprdrFileContentsRequest.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a CliprdrFileContentsRequest message.
         * @function verify
         * @memberof hbb.CliprdrFileContentsRequest
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        CliprdrFileContentsRequest.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.stream_id != null && message.hasOwnProperty("stream_id"))
                if (!$util.isInteger(message.stream_id))
                    return "stream_id: integer expected";
            if (message.list_index != null && message.hasOwnProperty("list_index"))
                if (!$util.isInteger(message.list_index))
                    return "list_index: integer expected";
            if (message.dw_flags != null && message.hasOwnProperty("dw_flags"))
                if (!$util.isInteger(message.dw_flags))
                    return "dw_flags: integer expected";
            if (message.n_position_low != null && message.hasOwnProperty("n_position_low"))
                if (!$util.isInteger(message.n_position_low))
                    return "n_position_low: integer expected";
            if (message.n_position_high != null && message.hasOwnProperty("n_position_high"))
                if (!$util.isInteger(message.n_position_high))
                    return "n_position_high: integer expected";
            if (message.cb_requested != null && message.hasOwnProperty("cb_requested"))
                if (!$util.isInteger(message.cb_requested))
                    return "cb_requested: integer expected";
            if (message.have_clip_data_id != null && message.hasOwnProperty("have_clip_data_id"))
                if (typeof message.have_clip_data_id !== "boolean")
                    return "have_clip_data_id: boolean expected";
            if (message.clip_data_id != null && message.hasOwnProperty("clip_data_id"))
                if (!$util.isInteger(message.clip_data_id))
                    return "clip_data_id: integer expected";
            return null;
        };

        /**
         * Creates a CliprdrFileContentsRequest message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.CliprdrFileContentsRequest
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.CliprdrFileContentsRequest} CliprdrFileContentsRequest
         */
        CliprdrFileContentsRequest.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.CliprdrFileContentsRequest)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.CliprdrFileContentsRequest();
            if (object.stream_id != null)
                message.stream_id = object.stream_id | 0;
            if (object.list_index != null)
                message.list_index = object.list_index | 0;
            if (object.dw_flags != null)
                message.dw_flags = object.dw_flags | 0;
            if (object.n_position_low != null)
                message.n_position_low = object.n_position_low | 0;
            if (object.n_position_high != null)
                message.n_position_high = object.n_position_high | 0;
            if (object.cb_requested != null)
                message.cb_requested = object.cb_requested | 0;
            if (object.have_clip_data_id != null)
                message.have_clip_data_id = Boolean(object.have_clip_data_id);
            if (object.clip_data_id != null)
                message.clip_data_id = object.clip_data_id | 0;
            return message;
        };

        /**
         * Creates a plain object from a CliprdrFileContentsRequest message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.CliprdrFileContentsRequest
         * @static
         * @param {hbb.CliprdrFileContentsRequest} message CliprdrFileContentsRequest
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        CliprdrFileContentsRequest.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.stream_id = 0;
                object.list_index = 0;
                object.dw_flags = 0;
                object.n_position_low = 0;
                object.n_position_high = 0;
                object.cb_requested = 0;
                object.have_clip_data_id = false;
                object.clip_data_id = 0;
            }
            if (message.stream_id != null && message.hasOwnProperty("stream_id"))
                object.stream_id = message.stream_id;
            if (message.list_index != null && message.hasOwnProperty("list_index"))
                object.list_index = message.list_index;
            if (message.dw_flags != null && message.hasOwnProperty("dw_flags"))
                object.dw_flags = message.dw_flags;
            if (message.n_position_low != null && message.hasOwnProperty("n_position_low"))
                object.n_position_low = message.n_position_low;
            if (message.n_position_high != null && message.hasOwnProperty("n_position_high"))
                object.n_position_high = message.n_position_high;
            if (message.cb_requested != null && message.hasOwnProperty("cb_requested"))
                object.cb_requested = message.cb_requested;
            if (message.have_clip_data_id != null && message.hasOwnProperty("have_clip_data_id"))
                object.have_clip_data_id = message.have_clip_data_id;
            if (message.clip_data_id != null && message.hasOwnProperty("clip_data_id"))
                object.clip_data_id = message.clip_data_id;
            return object;
        };

        /**
         * Converts this CliprdrFileContentsRequest to JSON.
         * @function toJSON
         * @memberof hbb.CliprdrFileContentsRequest
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        CliprdrFileContentsRequest.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for CliprdrFileContentsRequest
         * @function getTypeUrl
         * @memberof hbb.CliprdrFileContentsRequest
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        CliprdrFileContentsRequest.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.CliprdrFileContentsRequest";
        };

        return CliprdrFileContentsRequest;
    })();

    hbb.CliprdrFileContentsResponse = (function() {

        /**
         * Properties of a CliprdrFileContentsResponse.
         * @memberof hbb
         * @interface ICliprdrFileContentsResponse
         * @property {number|null} [msg_flags] CliprdrFileContentsResponse msg_flags
         * @property {number|null} [stream_id] CliprdrFileContentsResponse stream_id
         * @property {Uint8Array|null} [requested_data] CliprdrFileContentsResponse requested_data
         */

        /**
         * Constructs a new CliprdrFileContentsResponse.
         * @memberof hbb
         * @classdesc Represents a CliprdrFileContentsResponse.
         * @implements ICliprdrFileContentsResponse
         * @constructor
         * @param {hbb.ICliprdrFileContentsResponse=} [properties] Properties to set
         */
        function CliprdrFileContentsResponse(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * CliprdrFileContentsResponse msg_flags.
         * @member {number} msg_flags
         * @memberof hbb.CliprdrFileContentsResponse
         * @instance
         */
        CliprdrFileContentsResponse.prototype.msg_flags = 0;

        /**
         * CliprdrFileContentsResponse stream_id.
         * @member {number} stream_id
         * @memberof hbb.CliprdrFileContentsResponse
         * @instance
         */
        CliprdrFileContentsResponse.prototype.stream_id = 0;

        /**
         * CliprdrFileContentsResponse requested_data.
         * @member {Uint8Array} requested_data
         * @memberof hbb.CliprdrFileContentsResponse
         * @instance
         */
        CliprdrFileContentsResponse.prototype.requested_data = $util.newBuffer([]);

        /**
         * Creates a new CliprdrFileContentsResponse instance using the specified properties.
         * @function create
         * @memberof hbb.CliprdrFileContentsResponse
         * @static
         * @param {hbb.ICliprdrFileContentsResponse=} [properties] Properties to set
         * @returns {hbb.CliprdrFileContentsResponse} CliprdrFileContentsResponse instance
         */
        CliprdrFileContentsResponse.create = function create(properties) {
            return new CliprdrFileContentsResponse(properties);
        };

        /**
         * Encodes the specified CliprdrFileContentsResponse message. Does not implicitly {@link hbb.CliprdrFileContentsResponse.verify|verify} messages.
         * @function encode
         * @memberof hbb.CliprdrFileContentsResponse
         * @static
         * @param {hbb.ICliprdrFileContentsResponse} message CliprdrFileContentsResponse message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CliprdrFileContentsResponse.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.msg_flags != null && Object.hasOwnProperty.call(message, "msg_flags"))
                writer.uint32(/* id 3, wireType 0 =*/24).int32(message.msg_flags);
            if (message.stream_id != null && Object.hasOwnProperty.call(message, "stream_id"))
                writer.uint32(/* id 4, wireType 0 =*/32).int32(message.stream_id);
            if (message.requested_data != null && Object.hasOwnProperty.call(message, "requested_data"))
                writer.uint32(/* id 5, wireType 2 =*/42).bytes(message.requested_data);
            return writer;
        };

        /**
         * Encodes the specified CliprdrFileContentsResponse message, length delimited. Does not implicitly {@link hbb.CliprdrFileContentsResponse.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.CliprdrFileContentsResponse
         * @static
         * @param {hbb.ICliprdrFileContentsResponse} message CliprdrFileContentsResponse message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CliprdrFileContentsResponse.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a CliprdrFileContentsResponse message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.CliprdrFileContentsResponse
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.CliprdrFileContentsResponse} CliprdrFileContentsResponse
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CliprdrFileContentsResponse.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.CliprdrFileContentsResponse();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 3: {
                        message.msg_flags = reader.int32();
                        break;
                    }
                case 4: {
                        message.stream_id = reader.int32();
                        break;
                    }
                case 5: {
                        message.requested_data = reader.bytes();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a CliprdrFileContentsResponse message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.CliprdrFileContentsResponse
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.CliprdrFileContentsResponse} CliprdrFileContentsResponse
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CliprdrFileContentsResponse.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a CliprdrFileContentsResponse message.
         * @function verify
         * @memberof hbb.CliprdrFileContentsResponse
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        CliprdrFileContentsResponse.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.msg_flags != null && message.hasOwnProperty("msg_flags"))
                if (!$util.isInteger(message.msg_flags))
                    return "msg_flags: integer expected";
            if (message.stream_id != null && message.hasOwnProperty("stream_id"))
                if (!$util.isInteger(message.stream_id))
                    return "stream_id: integer expected";
            if (message.requested_data != null && message.hasOwnProperty("requested_data"))
                if (!(message.requested_data && typeof message.requested_data.length === "number" || $util.isString(message.requested_data)))
                    return "requested_data: buffer expected";
            return null;
        };

        /**
         * Creates a CliprdrFileContentsResponse message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.CliprdrFileContentsResponse
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.CliprdrFileContentsResponse} CliprdrFileContentsResponse
         */
        CliprdrFileContentsResponse.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.CliprdrFileContentsResponse)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.CliprdrFileContentsResponse();
            if (object.msg_flags != null)
                message.msg_flags = object.msg_flags | 0;
            if (object.stream_id != null)
                message.stream_id = object.stream_id | 0;
            if (object.requested_data != null)
                if (typeof object.requested_data === "string")
                    $util.base64.decode(object.requested_data, message.requested_data = $util.newBuffer($util.base64.length(object.requested_data)), 0);
                else if (object.requested_data.length >= 0)
                    message.requested_data = object.requested_data;
            return message;
        };

        /**
         * Creates a plain object from a CliprdrFileContentsResponse message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.CliprdrFileContentsResponse
         * @static
         * @param {hbb.CliprdrFileContentsResponse} message CliprdrFileContentsResponse
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        CliprdrFileContentsResponse.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.msg_flags = 0;
                object.stream_id = 0;
                if (options.bytes === String)
                    object.requested_data = "";
                else {
                    object.requested_data = [];
                    if (options.bytes !== Array)
                        object.requested_data = $util.newBuffer(object.requested_data);
                }
            }
            if (message.msg_flags != null && message.hasOwnProperty("msg_flags"))
                object.msg_flags = message.msg_flags;
            if (message.stream_id != null && message.hasOwnProperty("stream_id"))
                object.stream_id = message.stream_id;
            if (message.requested_data != null && message.hasOwnProperty("requested_data"))
                object.requested_data = options.bytes === String ? $util.base64.encode(message.requested_data, 0, message.requested_data.length) : options.bytes === Array ? Array.prototype.slice.call(message.requested_data) : message.requested_data;
            return object;
        };

        /**
         * Converts this CliprdrFileContentsResponse to JSON.
         * @function toJSON
         * @memberof hbb.CliprdrFileContentsResponse
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        CliprdrFileContentsResponse.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for CliprdrFileContentsResponse
         * @function getTypeUrl
         * @memberof hbb.CliprdrFileContentsResponse
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        CliprdrFileContentsResponse.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.CliprdrFileContentsResponse";
        };

        return CliprdrFileContentsResponse;
    })();

    hbb.CliprdrTryEmpty = (function() {

        /**
         * Properties of a CliprdrTryEmpty.
         * @memberof hbb
         * @interface ICliprdrTryEmpty
         */

        /**
         * Constructs a new CliprdrTryEmpty.
         * @memberof hbb
         * @classdesc Represents a CliprdrTryEmpty.
         * @implements ICliprdrTryEmpty
         * @constructor
         * @param {hbb.ICliprdrTryEmpty=} [properties] Properties to set
         */
        function CliprdrTryEmpty(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * Creates a new CliprdrTryEmpty instance using the specified properties.
         * @function create
         * @memberof hbb.CliprdrTryEmpty
         * @static
         * @param {hbb.ICliprdrTryEmpty=} [properties] Properties to set
         * @returns {hbb.CliprdrTryEmpty} CliprdrTryEmpty instance
         */
        CliprdrTryEmpty.create = function create(properties) {
            return new CliprdrTryEmpty(properties);
        };

        /**
         * Encodes the specified CliprdrTryEmpty message. Does not implicitly {@link hbb.CliprdrTryEmpty.verify|verify} messages.
         * @function encode
         * @memberof hbb.CliprdrTryEmpty
         * @static
         * @param {hbb.ICliprdrTryEmpty} message CliprdrTryEmpty message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CliprdrTryEmpty.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            return writer;
        };

        /**
         * Encodes the specified CliprdrTryEmpty message, length delimited. Does not implicitly {@link hbb.CliprdrTryEmpty.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.CliprdrTryEmpty
         * @static
         * @param {hbb.ICliprdrTryEmpty} message CliprdrTryEmpty message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CliprdrTryEmpty.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a CliprdrTryEmpty message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.CliprdrTryEmpty
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.CliprdrTryEmpty} CliprdrTryEmpty
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CliprdrTryEmpty.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.CliprdrTryEmpty();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a CliprdrTryEmpty message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.CliprdrTryEmpty
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.CliprdrTryEmpty} CliprdrTryEmpty
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CliprdrTryEmpty.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a CliprdrTryEmpty message.
         * @function verify
         * @memberof hbb.CliprdrTryEmpty
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        CliprdrTryEmpty.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            return null;
        };

        /**
         * Creates a CliprdrTryEmpty message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.CliprdrTryEmpty
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.CliprdrTryEmpty} CliprdrTryEmpty
         */
        CliprdrTryEmpty.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.CliprdrTryEmpty)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            return new $root.hbb.CliprdrTryEmpty();
        };

        /**
         * Creates a plain object from a CliprdrTryEmpty message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.CliprdrTryEmpty
         * @static
         * @param {hbb.CliprdrTryEmpty} message CliprdrTryEmpty
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        CliprdrTryEmpty.toObject = function toObject() {
            return {};
        };

        /**
         * Converts this CliprdrTryEmpty to JSON.
         * @function toJSON
         * @memberof hbb.CliprdrTryEmpty
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        CliprdrTryEmpty.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for CliprdrTryEmpty
         * @function getTypeUrl
         * @memberof hbb.CliprdrTryEmpty
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        CliprdrTryEmpty.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.CliprdrTryEmpty";
        };

        return CliprdrTryEmpty;
    })();

    hbb.Cliprdr = (function() {

        /**
         * Properties of a Cliprdr.
         * @memberof hbb
         * @interface ICliprdr
         * @property {hbb.ICliprdrMonitorReady|null} [ready] Cliprdr ready
         * @property {hbb.ICliprdrServerFormatList|null} [format_list] Cliprdr format_list
         * @property {hbb.ICliprdrServerFormatListResponse|null} [format_list_response] Cliprdr format_list_response
         * @property {hbb.ICliprdrServerFormatDataRequest|null} [format_data_request] Cliprdr format_data_request
         * @property {hbb.ICliprdrServerFormatDataResponse|null} [format_data_response] Cliprdr format_data_response
         * @property {hbb.ICliprdrFileContentsRequest|null} [file_contents_request] Cliprdr file_contents_request
         * @property {hbb.ICliprdrFileContentsResponse|null} [file_contents_response] Cliprdr file_contents_response
         * @property {hbb.ICliprdrTryEmpty|null} [try_empty] Cliprdr try_empty
         */

        /**
         * Constructs a new Cliprdr.
         * @memberof hbb
         * @classdesc Represents a Cliprdr.
         * @implements ICliprdr
         * @constructor
         * @param {hbb.ICliprdr=} [properties] Properties to set
         */
        function Cliprdr(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * Cliprdr ready.
         * @member {hbb.ICliprdrMonitorReady|null|undefined} ready
         * @memberof hbb.Cliprdr
         * @instance
         */
        Cliprdr.prototype.ready = null;

        /**
         * Cliprdr format_list.
         * @member {hbb.ICliprdrServerFormatList|null|undefined} format_list
         * @memberof hbb.Cliprdr
         * @instance
         */
        Cliprdr.prototype.format_list = null;

        /**
         * Cliprdr format_list_response.
         * @member {hbb.ICliprdrServerFormatListResponse|null|undefined} format_list_response
         * @memberof hbb.Cliprdr
         * @instance
         */
        Cliprdr.prototype.format_list_response = null;

        /**
         * Cliprdr format_data_request.
         * @member {hbb.ICliprdrServerFormatDataRequest|null|undefined} format_data_request
         * @memberof hbb.Cliprdr
         * @instance
         */
        Cliprdr.prototype.format_data_request = null;

        /**
         * Cliprdr format_data_response.
         * @member {hbb.ICliprdrServerFormatDataResponse|null|undefined} format_data_response
         * @memberof hbb.Cliprdr
         * @instance
         */
        Cliprdr.prototype.format_data_response = null;

        /**
         * Cliprdr file_contents_request.
         * @member {hbb.ICliprdrFileContentsRequest|null|undefined} file_contents_request
         * @memberof hbb.Cliprdr
         * @instance
         */
        Cliprdr.prototype.file_contents_request = null;

        /**
         * Cliprdr file_contents_response.
         * @member {hbb.ICliprdrFileContentsResponse|null|undefined} file_contents_response
         * @memberof hbb.Cliprdr
         * @instance
         */
        Cliprdr.prototype.file_contents_response = null;

        /**
         * Cliprdr try_empty.
         * @member {hbb.ICliprdrTryEmpty|null|undefined} try_empty
         * @memberof hbb.Cliprdr
         * @instance
         */
        Cliprdr.prototype.try_empty = null;

        // OneOf field names bound to virtual getters and setters
        let $oneOfFields;

        /**
         * Cliprdr union.
         * @member {"ready"|"format_list"|"format_list_response"|"format_data_request"|"format_data_response"|"file_contents_request"|"file_contents_response"|"try_empty"|undefined} union
         * @memberof hbb.Cliprdr
         * @instance
         */
        Object.defineProperty(Cliprdr.prototype, "union", {
            get: $util.oneOfGetter($oneOfFields = ["ready", "format_list", "format_list_response", "format_data_request", "format_data_response", "file_contents_request", "file_contents_response", "try_empty"]),
            set: $util.oneOfSetter($oneOfFields)
        });

        /**
         * Creates a new Cliprdr instance using the specified properties.
         * @function create
         * @memberof hbb.Cliprdr
         * @static
         * @param {hbb.ICliprdr=} [properties] Properties to set
         * @returns {hbb.Cliprdr} Cliprdr instance
         */
        Cliprdr.create = function create(properties) {
            return new Cliprdr(properties);
        };

        /**
         * Encodes the specified Cliprdr message. Does not implicitly {@link hbb.Cliprdr.verify|verify} messages.
         * @function encode
         * @memberof hbb.Cliprdr
         * @static
         * @param {hbb.ICliprdr} message Cliprdr message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Cliprdr.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.ready != null && Object.hasOwnProperty.call(message, "ready"))
                $root.hbb.CliprdrMonitorReady.encode(message.ready, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.format_list != null && Object.hasOwnProperty.call(message, "format_list"))
                $root.hbb.CliprdrServerFormatList.encode(message.format_list, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            if (message.format_list_response != null && Object.hasOwnProperty.call(message, "format_list_response"))
                $root.hbb.CliprdrServerFormatListResponse.encode(message.format_list_response, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
            if (message.format_data_request != null && Object.hasOwnProperty.call(message, "format_data_request"))
                $root.hbb.CliprdrServerFormatDataRequest.encode(message.format_data_request, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim();
            if (message.format_data_response != null && Object.hasOwnProperty.call(message, "format_data_response"))
                $root.hbb.CliprdrServerFormatDataResponse.encode(message.format_data_response, writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim();
            if (message.file_contents_request != null && Object.hasOwnProperty.call(message, "file_contents_request"))
                $root.hbb.CliprdrFileContentsRequest.encode(message.file_contents_request, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim();
            if (message.file_contents_response != null && Object.hasOwnProperty.call(message, "file_contents_response"))
                $root.hbb.CliprdrFileContentsResponse.encode(message.file_contents_response, writer.uint32(/* id 7, wireType 2 =*/58).fork()).ldelim();
            if (message.try_empty != null && Object.hasOwnProperty.call(message, "try_empty"))
                $root.hbb.CliprdrTryEmpty.encode(message.try_empty, writer.uint32(/* id 8, wireType 2 =*/66).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified Cliprdr message, length delimited. Does not implicitly {@link hbb.Cliprdr.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.Cliprdr
         * @static
         * @param {hbb.ICliprdr} message Cliprdr message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Cliprdr.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a Cliprdr message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.Cliprdr
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.Cliprdr} Cliprdr
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Cliprdr.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.Cliprdr();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.ready = $root.hbb.CliprdrMonitorReady.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 2: {
                        message.format_list = $root.hbb.CliprdrServerFormatList.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 3: {
                        message.format_list_response = $root.hbb.CliprdrServerFormatListResponse.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 4: {
                        message.format_data_request = $root.hbb.CliprdrServerFormatDataRequest.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 5: {
                        message.format_data_response = $root.hbb.CliprdrServerFormatDataResponse.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 6: {
                        message.file_contents_request = $root.hbb.CliprdrFileContentsRequest.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 7: {
                        message.file_contents_response = $root.hbb.CliprdrFileContentsResponse.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 8: {
                        message.try_empty = $root.hbb.CliprdrTryEmpty.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a Cliprdr message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.Cliprdr
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.Cliprdr} Cliprdr
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Cliprdr.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a Cliprdr message.
         * @function verify
         * @memberof hbb.Cliprdr
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        Cliprdr.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            let properties = {};
            if (message.ready != null && message.hasOwnProperty("ready")) {
                properties.union = 1;
                {
                    let error = $root.hbb.CliprdrMonitorReady.verify(message.ready, long + 1);
                    if (error)
                        return "ready." + error;
                }
            }
            if (message.format_list != null && message.hasOwnProperty("format_list")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.CliprdrServerFormatList.verify(message.format_list, long + 1);
                    if (error)
                        return "format_list." + error;
                }
            }
            if (message.format_list_response != null && message.hasOwnProperty("format_list_response")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.CliprdrServerFormatListResponse.verify(message.format_list_response, long + 1);
                    if (error)
                        return "format_list_response." + error;
                }
            }
            if (message.format_data_request != null && message.hasOwnProperty("format_data_request")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.CliprdrServerFormatDataRequest.verify(message.format_data_request, long + 1);
                    if (error)
                        return "format_data_request." + error;
                }
            }
            if (message.format_data_response != null && message.hasOwnProperty("format_data_response")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.CliprdrServerFormatDataResponse.verify(message.format_data_response, long + 1);
                    if (error)
                        return "format_data_response." + error;
                }
            }
            if (message.file_contents_request != null && message.hasOwnProperty("file_contents_request")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.CliprdrFileContentsRequest.verify(message.file_contents_request, long + 1);
                    if (error)
                        return "file_contents_request." + error;
                }
            }
            if (message.file_contents_response != null && message.hasOwnProperty("file_contents_response")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.CliprdrFileContentsResponse.verify(message.file_contents_response, long + 1);
                    if (error)
                        return "file_contents_response." + error;
                }
            }
            if (message.try_empty != null && message.hasOwnProperty("try_empty")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.CliprdrTryEmpty.verify(message.try_empty, long + 1);
                    if (error)
                        return "try_empty." + error;
                }
            }
            return null;
        };

        /**
         * Creates a Cliprdr message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.Cliprdr
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.Cliprdr} Cliprdr
         */
        Cliprdr.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.Cliprdr)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.Cliprdr();
            if (object.ready != null) {
                if (typeof object.ready !== "object")
                    throw TypeError(".hbb.Cliprdr.ready: object expected");
                message.ready = $root.hbb.CliprdrMonitorReady.fromObject(object.ready, long + 1);
            }
            if (object.format_list != null) {
                if (typeof object.format_list !== "object")
                    throw TypeError(".hbb.Cliprdr.format_list: object expected");
                message.format_list = $root.hbb.CliprdrServerFormatList.fromObject(object.format_list, long + 1);
            }
            if (object.format_list_response != null) {
                if (typeof object.format_list_response !== "object")
                    throw TypeError(".hbb.Cliprdr.format_list_response: object expected");
                message.format_list_response = $root.hbb.CliprdrServerFormatListResponse.fromObject(object.format_list_response, long + 1);
            }
            if (object.format_data_request != null) {
                if (typeof object.format_data_request !== "object")
                    throw TypeError(".hbb.Cliprdr.format_data_request: object expected");
                message.format_data_request = $root.hbb.CliprdrServerFormatDataRequest.fromObject(object.format_data_request, long + 1);
            }
            if (object.format_data_response != null) {
                if (typeof object.format_data_response !== "object")
                    throw TypeError(".hbb.Cliprdr.format_data_response: object expected");
                message.format_data_response = $root.hbb.CliprdrServerFormatDataResponse.fromObject(object.format_data_response, long + 1);
            }
            if (object.file_contents_request != null) {
                if (typeof object.file_contents_request !== "object")
                    throw TypeError(".hbb.Cliprdr.file_contents_request: object expected");
                message.file_contents_request = $root.hbb.CliprdrFileContentsRequest.fromObject(object.file_contents_request, long + 1);
            }
            if (object.file_contents_response != null) {
                if (typeof object.file_contents_response !== "object")
                    throw TypeError(".hbb.Cliprdr.file_contents_response: object expected");
                message.file_contents_response = $root.hbb.CliprdrFileContentsResponse.fromObject(object.file_contents_response, long + 1);
            }
            if (object.try_empty != null) {
                if (typeof object.try_empty !== "object")
                    throw TypeError(".hbb.Cliprdr.try_empty: object expected");
                message.try_empty = $root.hbb.CliprdrTryEmpty.fromObject(object.try_empty, long + 1);
            }
            return message;
        };

        /**
         * Creates a plain object from a Cliprdr message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.Cliprdr
         * @static
         * @param {hbb.Cliprdr} message Cliprdr
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        Cliprdr.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (message.ready != null && message.hasOwnProperty("ready")) {
                object.ready = $root.hbb.CliprdrMonitorReady.toObject(message.ready, options);
                if (options.oneofs)
                    object.union = "ready";
            }
            if (message.format_list != null && message.hasOwnProperty("format_list")) {
                object.format_list = $root.hbb.CliprdrServerFormatList.toObject(message.format_list, options);
                if (options.oneofs)
                    object.union = "format_list";
            }
            if (message.format_list_response != null && message.hasOwnProperty("format_list_response")) {
                object.format_list_response = $root.hbb.CliprdrServerFormatListResponse.toObject(message.format_list_response, options);
                if (options.oneofs)
                    object.union = "format_list_response";
            }
            if (message.format_data_request != null && message.hasOwnProperty("format_data_request")) {
                object.format_data_request = $root.hbb.CliprdrServerFormatDataRequest.toObject(message.format_data_request, options);
                if (options.oneofs)
                    object.union = "format_data_request";
            }
            if (message.format_data_response != null && message.hasOwnProperty("format_data_response")) {
                object.format_data_response = $root.hbb.CliprdrServerFormatDataResponse.toObject(message.format_data_response, options);
                if (options.oneofs)
                    object.union = "format_data_response";
            }
            if (message.file_contents_request != null && message.hasOwnProperty("file_contents_request")) {
                object.file_contents_request = $root.hbb.CliprdrFileContentsRequest.toObject(message.file_contents_request, options);
                if (options.oneofs)
                    object.union = "file_contents_request";
            }
            if (message.file_contents_response != null && message.hasOwnProperty("file_contents_response")) {
                object.file_contents_response = $root.hbb.CliprdrFileContentsResponse.toObject(message.file_contents_response, options);
                if (options.oneofs)
                    object.union = "file_contents_response";
            }
            if (message.try_empty != null && message.hasOwnProperty("try_empty")) {
                object.try_empty = $root.hbb.CliprdrTryEmpty.toObject(message.try_empty, options);
                if (options.oneofs)
                    object.union = "try_empty";
            }
            return object;
        };

        /**
         * Converts this Cliprdr to JSON.
         * @function toJSON
         * @memberof hbb.Cliprdr
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        Cliprdr.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for Cliprdr
         * @function getTypeUrl
         * @memberof hbb.Cliprdr
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        Cliprdr.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.Cliprdr";
        };

        return Cliprdr;
    })();

    hbb.Resolution = (function() {

        /**
         * Properties of a Resolution.
         * @memberof hbb
         * @interface IResolution
         * @property {number|null} [width] Resolution width
         * @property {number|null} [height] Resolution height
         */

        /**
         * Constructs a new Resolution.
         * @memberof hbb
         * @classdesc Represents a Resolution.
         * @implements IResolution
         * @constructor
         * @param {hbb.IResolution=} [properties] Properties to set
         */
        function Resolution(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * Resolution width.
         * @member {number} width
         * @memberof hbb.Resolution
         * @instance
         */
        Resolution.prototype.width = 0;

        /**
         * Resolution height.
         * @member {number} height
         * @memberof hbb.Resolution
         * @instance
         */
        Resolution.prototype.height = 0;

        /**
         * Creates a new Resolution instance using the specified properties.
         * @function create
         * @memberof hbb.Resolution
         * @static
         * @param {hbb.IResolution=} [properties] Properties to set
         * @returns {hbb.Resolution} Resolution instance
         */
        Resolution.create = function create(properties) {
            return new Resolution(properties);
        };

        /**
         * Encodes the specified Resolution message. Does not implicitly {@link hbb.Resolution.verify|verify} messages.
         * @function encode
         * @memberof hbb.Resolution
         * @static
         * @param {hbb.IResolution} message Resolution message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Resolution.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.width != null && Object.hasOwnProperty.call(message, "width"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.width);
            if (message.height != null && Object.hasOwnProperty.call(message, "height"))
                writer.uint32(/* id 2, wireType 0 =*/16).int32(message.height);
            return writer;
        };

        /**
         * Encodes the specified Resolution message, length delimited. Does not implicitly {@link hbb.Resolution.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.Resolution
         * @static
         * @param {hbb.IResolution} message Resolution message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Resolution.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a Resolution message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.Resolution
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.Resolution} Resolution
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Resolution.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.Resolution();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.width = reader.int32();
                        break;
                    }
                case 2: {
                        message.height = reader.int32();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a Resolution message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.Resolution
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.Resolution} Resolution
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Resolution.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a Resolution message.
         * @function verify
         * @memberof hbb.Resolution
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        Resolution.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.width != null && message.hasOwnProperty("width"))
                if (!$util.isInteger(message.width))
                    return "width: integer expected";
            if (message.height != null && message.hasOwnProperty("height"))
                if (!$util.isInteger(message.height))
                    return "height: integer expected";
            return null;
        };

        /**
         * Creates a Resolution message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.Resolution
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.Resolution} Resolution
         */
        Resolution.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.Resolution)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.Resolution();
            if (object.width != null)
                message.width = object.width | 0;
            if (object.height != null)
                message.height = object.height | 0;
            return message;
        };

        /**
         * Creates a plain object from a Resolution message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.Resolution
         * @static
         * @param {hbb.Resolution} message Resolution
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        Resolution.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.width = 0;
                object.height = 0;
            }
            if (message.width != null && message.hasOwnProperty("width"))
                object.width = message.width;
            if (message.height != null && message.hasOwnProperty("height"))
                object.height = message.height;
            return object;
        };

        /**
         * Converts this Resolution to JSON.
         * @function toJSON
         * @memberof hbb.Resolution
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        Resolution.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for Resolution
         * @function getTypeUrl
         * @memberof hbb.Resolution
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        Resolution.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.Resolution";
        };

        return Resolution;
    })();

    hbb.DisplayResolution = (function() {

        /**
         * Properties of a DisplayResolution.
         * @memberof hbb
         * @interface IDisplayResolution
         * @property {number|null} [display] DisplayResolution display
         * @property {hbb.IResolution|null} [resolution] DisplayResolution resolution
         */

        /**
         * Constructs a new DisplayResolution.
         * @memberof hbb
         * @classdesc Represents a DisplayResolution.
         * @implements IDisplayResolution
         * @constructor
         * @param {hbb.IDisplayResolution=} [properties] Properties to set
         */
        function DisplayResolution(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * DisplayResolution display.
         * @member {number} display
         * @memberof hbb.DisplayResolution
         * @instance
         */
        DisplayResolution.prototype.display = 0;

        /**
         * DisplayResolution resolution.
         * @member {hbb.IResolution|null|undefined} resolution
         * @memberof hbb.DisplayResolution
         * @instance
         */
        DisplayResolution.prototype.resolution = null;

        /**
         * Creates a new DisplayResolution instance using the specified properties.
         * @function create
         * @memberof hbb.DisplayResolution
         * @static
         * @param {hbb.IDisplayResolution=} [properties] Properties to set
         * @returns {hbb.DisplayResolution} DisplayResolution instance
         */
        DisplayResolution.create = function create(properties) {
            return new DisplayResolution(properties);
        };

        /**
         * Encodes the specified DisplayResolution message. Does not implicitly {@link hbb.DisplayResolution.verify|verify} messages.
         * @function encode
         * @memberof hbb.DisplayResolution
         * @static
         * @param {hbb.IDisplayResolution} message DisplayResolution message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        DisplayResolution.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.display != null && Object.hasOwnProperty.call(message, "display"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.display);
            if (message.resolution != null && Object.hasOwnProperty.call(message, "resolution"))
                $root.hbb.Resolution.encode(message.resolution, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified DisplayResolution message, length delimited. Does not implicitly {@link hbb.DisplayResolution.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.DisplayResolution
         * @static
         * @param {hbb.IDisplayResolution} message DisplayResolution message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        DisplayResolution.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a DisplayResolution message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.DisplayResolution
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.DisplayResolution} DisplayResolution
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        DisplayResolution.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.DisplayResolution();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.display = reader.int32();
                        break;
                    }
                case 2: {
                        message.resolution = $root.hbb.Resolution.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a DisplayResolution message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.DisplayResolution
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.DisplayResolution} DisplayResolution
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        DisplayResolution.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a DisplayResolution message.
         * @function verify
         * @memberof hbb.DisplayResolution
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        DisplayResolution.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.display != null && message.hasOwnProperty("display"))
                if (!$util.isInteger(message.display))
                    return "display: integer expected";
            if (message.resolution != null && message.hasOwnProperty("resolution")) {
                let error = $root.hbb.Resolution.verify(message.resolution, long + 1);
                if (error)
                    return "resolution." + error;
            }
            return null;
        };

        /**
         * Creates a DisplayResolution message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.DisplayResolution
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.DisplayResolution} DisplayResolution
         */
        DisplayResolution.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.DisplayResolution)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.DisplayResolution();
            if (object.display != null)
                message.display = object.display | 0;
            if (object.resolution != null) {
                if (typeof object.resolution !== "object")
                    throw TypeError(".hbb.DisplayResolution.resolution: object expected");
                message.resolution = $root.hbb.Resolution.fromObject(object.resolution, long + 1);
            }
            return message;
        };

        /**
         * Creates a plain object from a DisplayResolution message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.DisplayResolution
         * @static
         * @param {hbb.DisplayResolution} message DisplayResolution
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        DisplayResolution.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.display = 0;
                object.resolution = null;
            }
            if (message.display != null && message.hasOwnProperty("display"))
                object.display = message.display;
            if (message.resolution != null && message.hasOwnProperty("resolution"))
                object.resolution = $root.hbb.Resolution.toObject(message.resolution, options);
            return object;
        };

        /**
         * Converts this DisplayResolution to JSON.
         * @function toJSON
         * @memberof hbb.DisplayResolution
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        DisplayResolution.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for DisplayResolution
         * @function getTypeUrl
         * @memberof hbb.DisplayResolution
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        DisplayResolution.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.DisplayResolution";
        };

        return DisplayResolution;
    })();

    hbb.SupportedResolutions = (function() {

        /**
         * Properties of a SupportedResolutions.
         * @memberof hbb
         * @interface ISupportedResolutions
         * @property {Array.<hbb.IResolution>|null} [resolutions] SupportedResolutions resolutions
         */

        /**
         * Constructs a new SupportedResolutions.
         * @memberof hbb
         * @classdesc Represents a SupportedResolutions.
         * @implements ISupportedResolutions
         * @constructor
         * @param {hbb.ISupportedResolutions=} [properties] Properties to set
         */
        function SupportedResolutions(properties) {
            this.resolutions = [];
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * SupportedResolutions resolutions.
         * @member {Array.<hbb.IResolution>} resolutions
         * @memberof hbb.SupportedResolutions
         * @instance
         */
        SupportedResolutions.prototype.resolutions = $util.emptyArray;

        /**
         * Creates a new SupportedResolutions instance using the specified properties.
         * @function create
         * @memberof hbb.SupportedResolutions
         * @static
         * @param {hbb.ISupportedResolutions=} [properties] Properties to set
         * @returns {hbb.SupportedResolutions} SupportedResolutions instance
         */
        SupportedResolutions.create = function create(properties) {
            return new SupportedResolutions(properties);
        };

        /**
         * Encodes the specified SupportedResolutions message. Does not implicitly {@link hbb.SupportedResolutions.verify|verify} messages.
         * @function encode
         * @memberof hbb.SupportedResolutions
         * @static
         * @param {hbb.ISupportedResolutions} message SupportedResolutions message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SupportedResolutions.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.resolutions != null && message.resolutions.length)
                for (let i = 0; i < message.resolutions.length; ++i)
                    $root.hbb.Resolution.encode(message.resolutions[i], writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified SupportedResolutions message, length delimited. Does not implicitly {@link hbb.SupportedResolutions.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.SupportedResolutions
         * @static
         * @param {hbb.ISupportedResolutions} message SupportedResolutions message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SupportedResolutions.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a SupportedResolutions message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.SupportedResolutions
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.SupportedResolutions} SupportedResolutions
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SupportedResolutions.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.SupportedResolutions();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        if (!(message.resolutions && message.resolutions.length))
                            message.resolutions = [];
                        message.resolutions.push($root.hbb.Resolution.decode(reader, reader.uint32(), undefined, long + 1));
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a SupportedResolutions message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.SupportedResolutions
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.SupportedResolutions} SupportedResolutions
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SupportedResolutions.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a SupportedResolutions message.
         * @function verify
         * @memberof hbb.SupportedResolutions
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        SupportedResolutions.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.resolutions != null && message.hasOwnProperty("resolutions")) {
                if (!Array.isArray(message.resolutions))
                    return "resolutions: array expected";
                for (let i = 0; i < message.resolutions.length; ++i) {
                    let error = $root.hbb.Resolution.verify(message.resolutions[i], long + 1);
                    if (error)
                        return "resolutions." + error;
                }
            }
            return null;
        };

        /**
         * Creates a SupportedResolutions message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.SupportedResolutions
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.SupportedResolutions} SupportedResolutions
         */
        SupportedResolutions.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.SupportedResolutions)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.SupportedResolutions();
            if (object.resolutions) {
                if (!Array.isArray(object.resolutions))
                    throw TypeError(".hbb.SupportedResolutions.resolutions: array expected");
                message.resolutions = [];
                for (let i = 0; i < object.resolutions.length; ++i) {
                    if (typeof object.resolutions[i] !== "object")
                        throw TypeError(".hbb.SupportedResolutions.resolutions: object expected");
                    message.resolutions[i] = $root.hbb.Resolution.fromObject(object.resolutions[i], long + 1);
                }
            }
            return message;
        };

        /**
         * Creates a plain object from a SupportedResolutions message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.SupportedResolutions
         * @static
         * @param {hbb.SupportedResolutions} message SupportedResolutions
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        SupportedResolutions.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.arrays || options.defaults)
                object.resolutions = [];
            if (message.resolutions && message.resolutions.length) {
                object.resolutions = [];
                for (let j = 0; j < message.resolutions.length; ++j)
                    object.resolutions[j] = $root.hbb.Resolution.toObject(message.resolutions[j], options);
            }
            return object;
        };

        /**
         * Converts this SupportedResolutions to JSON.
         * @function toJSON
         * @memberof hbb.SupportedResolutions
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        SupportedResolutions.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for SupportedResolutions
         * @function getTypeUrl
         * @memberof hbb.SupportedResolutions
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        SupportedResolutions.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.SupportedResolutions";
        };

        return SupportedResolutions;
    })();

    hbb.SwitchDisplay = (function() {

        /**
         * Properties of a SwitchDisplay.
         * @memberof hbb
         * @interface ISwitchDisplay
         * @property {number|null} [display] SwitchDisplay display
         * @property {number|null} [x] SwitchDisplay x
         * @property {number|null} [y] SwitchDisplay y
         * @property {number|null} [width] SwitchDisplay width
         * @property {number|null} [height] SwitchDisplay height
         * @property {boolean|null} [cursor_embedded] SwitchDisplay cursor_embedded
         * @property {hbb.ISupportedResolutions|null} [resolutions] SwitchDisplay resolutions
         * @property {hbb.IResolution|null} [original_resolution] SwitchDisplay original_resolution
         */

        /**
         * Constructs a new SwitchDisplay.
         * @memberof hbb
         * @classdesc Represents a SwitchDisplay.
         * @implements ISwitchDisplay
         * @constructor
         * @param {hbb.ISwitchDisplay=} [properties] Properties to set
         */
        function SwitchDisplay(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * SwitchDisplay display.
         * @member {number} display
         * @memberof hbb.SwitchDisplay
         * @instance
         */
        SwitchDisplay.prototype.display = 0;

        /**
         * SwitchDisplay x.
         * @member {number} x
         * @memberof hbb.SwitchDisplay
         * @instance
         */
        SwitchDisplay.prototype.x = 0;

        /**
         * SwitchDisplay y.
         * @member {number} y
         * @memberof hbb.SwitchDisplay
         * @instance
         */
        SwitchDisplay.prototype.y = 0;

        /**
         * SwitchDisplay width.
         * @member {number} width
         * @memberof hbb.SwitchDisplay
         * @instance
         */
        SwitchDisplay.prototype.width = 0;

        /**
         * SwitchDisplay height.
         * @member {number} height
         * @memberof hbb.SwitchDisplay
         * @instance
         */
        SwitchDisplay.prototype.height = 0;

        /**
         * SwitchDisplay cursor_embedded.
         * @member {boolean} cursor_embedded
         * @memberof hbb.SwitchDisplay
         * @instance
         */
        SwitchDisplay.prototype.cursor_embedded = false;

        /**
         * SwitchDisplay resolutions.
         * @member {hbb.ISupportedResolutions|null|undefined} resolutions
         * @memberof hbb.SwitchDisplay
         * @instance
         */
        SwitchDisplay.prototype.resolutions = null;

        /**
         * SwitchDisplay original_resolution.
         * @member {hbb.IResolution|null|undefined} original_resolution
         * @memberof hbb.SwitchDisplay
         * @instance
         */
        SwitchDisplay.prototype.original_resolution = null;

        /**
         * Creates a new SwitchDisplay instance using the specified properties.
         * @function create
         * @memberof hbb.SwitchDisplay
         * @static
         * @param {hbb.ISwitchDisplay=} [properties] Properties to set
         * @returns {hbb.SwitchDisplay} SwitchDisplay instance
         */
        SwitchDisplay.create = function create(properties) {
            return new SwitchDisplay(properties);
        };

        /**
         * Encodes the specified SwitchDisplay message. Does not implicitly {@link hbb.SwitchDisplay.verify|verify} messages.
         * @function encode
         * @memberof hbb.SwitchDisplay
         * @static
         * @param {hbb.ISwitchDisplay} message SwitchDisplay message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SwitchDisplay.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.display != null && Object.hasOwnProperty.call(message, "display"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.display);
            if (message.x != null && Object.hasOwnProperty.call(message, "x"))
                writer.uint32(/* id 2, wireType 0 =*/16).sint32(message.x);
            if (message.y != null && Object.hasOwnProperty.call(message, "y"))
                writer.uint32(/* id 3, wireType 0 =*/24).sint32(message.y);
            if (message.width != null && Object.hasOwnProperty.call(message, "width"))
                writer.uint32(/* id 4, wireType 0 =*/32).int32(message.width);
            if (message.height != null && Object.hasOwnProperty.call(message, "height"))
                writer.uint32(/* id 5, wireType 0 =*/40).int32(message.height);
            if (message.cursor_embedded != null && Object.hasOwnProperty.call(message, "cursor_embedded"))
                writer.uint32(/* id 6, wireType 0 =*/48).bool(message.cursor_embedded);
            if (message.resolutions != null && Object.hasOwnProperty.call(message, "resolutions"))
                $root.hbb.SupportedResolutions.encode(message.resolutions, writer.uint32(/* id 7, wireType 2 =*/58).fork()).ldelim();
            if (message.original_resolution != null && Object.hasOwnProperty.call(message, "original_resolution"))
                $root.hbb.Resolution.encode(message.original_resolution, writer.uint32(/* id 8, wireType 2 =*/66).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified SwitchDisplay message, length delimited. Does not implicitly {@link hbb.SwitchDisplay.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.SwitchDisplay
         * @static
         * @param {hbb.ISwitchDisplay} message SwitchDisplay message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SwitchDisplay.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a SwitchDisplay message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.SwitchDisplay
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.SwitchDisplay} SwitchDisplay
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SwitchDisplay.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.SwitchDisplay();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.display = reader.int32();
                        break;
                    }
                case 2: {
                        message.x = reader.sint32();
                        break;
                    }
                case 3: {
                        message.y = reader.sint32();
                        break;
                    }
                case 4: {
                        message.width = reader.int32();
                        break;
                    }
                case 5: {
                        message.height = reader.int32();
                        break;
                    }
                case 6: {
                        message.cursor_embedded = reader.bool();
                        break;
                    }
                case 7: {
                        message.resolutions = $root.hbb.SupportedResolutions.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 8: {
                        message.original_resolution = $root.hbb.Resolution.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a SwitchDisplay message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.SwitchDisplay
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.SwitchDisplay} SwitchDisplay
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SwitchDisplay.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a SwitchDisplay message.
         * @function verify
         * @memberof hbb.SwitchDisplay
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        SwitchDisplay.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.display != null && message.hasOwnProperty("display"))
                if (!$util.isInteger(message.display))
                    return "display: integer expected";
            if (message.x != null && message.hasOwnProperty("x"))
                if (!$util.isInteger(message.x))
                    return "x: integer expected";
            if (message.y != null && message.hasOwnProperty("y"))
                if (!$util.isInteger(message.y))
                    return "y: integer expected";
            if (message.width != null && message.hasOwnProperty("width"))
                if (!$util.isInteger(message.width))
                    return "width: integer expected";
            if (message.height != null && message.hasOwnProperty("height"))
                if (!$util.isInteger(message.height))
                    return "height: integer expected";
            if (message.cursor_embedded != null && message.hasOwnProperty("cursor_embedded"))
                if (typeof message.cursor_embedded !== "boolean")
                    return "cursor_embedded: boolean expected";
            if (message.resolutions != null && message.hasOwnProperty("resolutions")) {
                let error = $root.hbb.SupportedResolutions.verify(message.resolutions, long + 1);
                if (error)
                    return "resolutions." + error;
            }
            if (message.original_resolution != null && message.hasOwnProperty("original_resolution")) {
                let error = $root.hbb.Resolution.verify(message.original_resolution, long + 1);
                if (error)
                    return "original_resolution." + error;
            }
            return null;
        };

        /**
         * Creates a SwitchDisplay message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.SwitchDisplay
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.SwitchDisplay} SwitchDisplay
         */
        SwitchDisplay.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.SwitchDisplay)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.SwitchDisplay();
            if (object.display != null)
                message.display = object.display | 0;
            if (object.x != null)
                message.x = object.x | 0;
            if (object.y != null)
                message.y = object.y | 0;
            if (object.width != null)
                message.width = object.width | 0;
            if (object.height != null)
                message.height = object.height | 0;
            if (object.cursor_embedded != null)
                message.cursor_embedded = Boolean(object.cursor_embedded);
            if (object.resolutions != null) {
                if (typeof object.resolutions !== "object")
                    throw TypeError(".hbb.SwitchDisplay.resolutions: object expected");
                message.resolutions = $root.hbb.SupportedResolutions.fromObject(object.resolutions, long + 1);
            }
            if (object.original_resolution != null) {
                if (typeof object.original_resolution !== "object")
                    throw TypeError(".hbb.SwitchDisplay.original_resolution: object expected");
                message.original_resolution = $root.hbb.Resolution.fromObject(object.original_resolution, long + 1);
            }
            return message;
        };

        /**
         * Creates a plain object from a SwitchDisplay message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.SwitchDisplay
         * @static
         * @param {hbb.SwitchDisplay} message SwitchDisplay
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        SwitchDisplay.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.display = 0;
                object.x = 0;
                object.y = 0;
                object.width = 0;
                object.height = 0;
                object.cursor_embedded = false;
                object.resolutions = null;
                object.original_resolution = null;
            }
            if (message.display != null && message.hasOwnProperty("display"))
                object.display = message.display;
            if (message.x != null && message.hasOwnProperty("x"))
                object.x = message.x;
            if (message.y != null && message.hasOwnProperty("y"))
                object.y = message.y;
            if (message.width != null && message.hasOwnProperty("width"))
                object.width = message.width;
            if (message.height != null && message.hasOwnProperty("height"))
                object.height = message.height;
            if (message.cursor_embedded != null && message.hasOwnProperty("cursor_embedded"))
                object.cursor_embedded = message.cursor_embedded;
            if (message.resolutions != null && message.hasOwnProperty("resolutions"))
                object.resolutions = $root.hbb.SupportedResolutions.toObject(message.resolutions, options);
            if (message.original_resolution != null && message.hasOwnProperty("original_resolution"))
                object.original_resolution = $root.hbb.Resolution.toObject(message.original_resolution, options);
            return object;
        };

        /**
         * Converts this SwitchDisplay to JSON.
         * @function toJSON
         * @memberof hbb.SwitchDisplay
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        SwitchDisplay.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for SwitchDisplay
         * @function getTypeUrl
         * @memberof hbb.SwitchDisplay
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        SwitchDisplay.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.SwitchDisplay";
        };

        return SwitchDisplay;
    })();

    hbb.CaptureDisplays = (function() {

        /**
         * Properties of a CaptureDisplays.
         * @memberof hbb
         * @interface ICaptureDisplays
         * @property {Array.<number>|null} [add] CaptureDisplays add
         * @property {Array.<number>|null} [sub] CaptureDisplays sub
         * @property {Array.<number>|null} [set] CaptureDisplays set
         */

        /**
         * Constructs a new CaptureDisplays.
         * @memberof hbb
         * @classdesc Represents a CaptureDisplays.
         * @implements ICaptureDisplays
         * @constructor
         * @param {hbb.ICaptureDisplays=} [properties] Properties to set
         */
        function CaptureDisplays(properties) {
            this.add = [];
            this.sub = [];
            this.set = [];
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * CaptureDisplays add.
         * @member {Array.<number>} add
         * @memberof hbb.CaptureDisplays
         * @instance
         */
        CaptureDisplays.prototype.add = $util.emptyArray;

        /**
         * CaptureDisplays sub.
         * @member {Array.<number>} sub
         * @memberof hbb.CaptureDisplays
         * @instance
         */
        CaptureDisplays.prototype.sub = $util.emptyArray;

        /**
         * CaptureDisplays set.
         * @member {Array.<number>} set
         * @memberof hbb.CaptureDisplays
         * @instance
         */
        CaptureDisplays.prototype.set = $util.emptyArray;

        /**
         * Creates a new CaptureDisplays instance using the specified properties.
         * @function create
         * @memberof hbb.CaptureDisplays
         * @static
         * @param {hbb.ICaptureDisplays=} [properties] Properties to set
         * @returns {hbb.CaptureDisplays} CaptureDisplays instance
         */
        CaptureDisplays.create = function create(properties) {
            return new CaptureDisplays(properties);
        };

        /**
         * Encodes the specified CaptureDisplays message. Does not implicitly {@link hbb.CaptureDisplays.verify|verify} messages.
         * @function encode
         * @memberof hbb.CaptureDisplays
         * @static
         * @param {hbb.ICaptureDisplays} message CaptureDisplays message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CaptureDisplays.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.add != null && message.add.length) {
                writer.uint32(/* id 1, wireType 2 =*/10).fork();
                for (let i = 0; i < message.add.length; ++i)
                    writer.int32(message.add[i]);
                writer.ldelim();
            }
            if (message.sub != null && message.sub.length) {
                writer.uint32(/* id 2, wireType 2 =*/18).fork();
                for (let i = 0; i < message.sub.length; ++i)
                    writer.int32(message.sub[i]);
                writer.ldelim();
            }
            if (message.set != null && message.set.length) {
                writer.uint32(/* id 3, wireType 2 =*/26).fork();
                for (let i = 0; i < message.set.length; ++i)
                    writer.int32(message.set[i]);
                writer.ldelim();
            }
            return writer;
        };

        /**
         * Encodes the specified CaptureDisplays message, length delimited. Does not implicitly {@link hbb.CaptureDisplays.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.CaptureDisplays
         * @static
         * @param {hbb.ICaptureDisplays} message CaptureDisplays message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CaptureDisplays.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a CaptureDisplays message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.CaptureDisplays
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.CaptureDisplays} CaptureDisplays
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CaptureDisplays.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.CaptureDisplays();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        if (!(message.add && message.add.length))
                            message.add = [];
                        if ((tag & 7) === 2) {
                            let end2 = reader.uint32() + reader.pos;
                            while (reader.pos < end2)
                                message.add.push(reader.int32());
                        } else
                            message.add.push(reader.int32());
                        break;
                    }
                case 2: {
                        if (!(message.sub && message.sub.length))
                            message.sub = [];
                        if ((tag & 7) === 2) {
                            let end2 = reader.uint32() + reader.pos;
                            while (reader.pos < end2)
                                message.sub.push(reader.int32());
                        } else
                            message.sub.push(reader.int32());
                        break;
                    }
                case 3: {
                        if (!(message.set && message.set.length))
                            message.set = [];
                        if ((tag & 7) === 2) {
                            let end2 = reader.uint32() + reader.pos;
                            while (reader.pos < end2)
                                message.set.push(reader.int32());
                        } else
                            message.set.push(reader.int32());
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a CaptureDisplays message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.CaptureDisplays
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.CaptureDisplays} CaptureDisplays
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CaptureDisplays.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a CaptureDisplays message.
         * @function verify
         * @memberof hbb.CaptureDisplays
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        CaptureDisplays.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.add != null && message.hasOwnProperty("add")) {
                if (!Array.isArray(message.add))
                    return "add: array expected";
                for (let i = 0; i < message.add.length; ++i)
                    if (!$util.isInteger(message.add[i]))
                        return "add: integer[] expected";
            }
            if (message.sub != null && message.hasOwnProperty("sub")) {
                if (!Array.isArray(message.sub))
                    return "sub: array expected";
                for (let i = 0; i < message.sub.length; ++i)
                    if (!$util.isInteger(message.sub[i]))
                        return "sub: integer[] expected";
            }
            if (message.set != null && message.hasOwnProperty("set")) {
                if (!Array.isArray(message.set))
                    return "set: array expected";
                for (let i = 0; i < message.set.length; ++i)
                    if (!$util.isInteger(message.set[i]))
                        return "set: integer[] expected";
            }
            return null;
        };

        /**
         * Creates a CaptureDisplays message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.CaptureDisplays
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.CaptureDisplays} CaptureDisplays
         */
        CaptureDisplays.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.CaptureDisplays)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.CaptureDisplays();
            if (object.add) {
                if (!Array.isArray(object.add))
                    throw TypeError(".hbb.CaptureDisplays.add: array expected");
                message.add = [];
                for (let i = 0; i < object.add.length; ++i)
                    message.add[i] = object.add[i] | 0;
            }
            if (object.sub) {
                if (!Array.isArray(object.sub))
                    throw TypeError(".hbb.CaptureDisplays.sub: array expected");
                message.sub = [];
                for (let i = 0; i < object.sub.length; ++i)
                    message.sub[i] = object.sub[i] | 0;
            }
            if (object.set) {
                if (!Array.isArray(object.set))
                    throw TypeError(".hbb.CaptureDisplays.set: array expected");
                message.set = [];
                for (let i = 0; i < object.set.length; ++i)
                    message.set[i] = object.set[i] | 0;
            }
            return message;
        };

        /**
         * Creates a plain object from a CaptureDisplays message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.CaptureDisplays
         * @static
         * @param {hbb.CaptureDisplays} message CaptureDisplays
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        CaptureDisplays.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.arrays || options.defaults) {
                object.add = [];
                object.sub = [];
                object.set = [];
            }
            if (message.add && message.add.length) {
                object.add = [];
                for (let j = 0; j < message.add.length; ++j)
                    object.add[j] = message.add[j];
            }
            if (message.sub && message.sub.length) {
                object.sub = [];
                for (let j = 0; j < message.sub.length; ++j)
                    object.sub[j] = message.sub[j];
            }
            if (message.set && message.set.length) {
                object.set = [];
                for (let j = 0; j < message.set.length; ++j)
                    object.set[j] = message.set[j];
            }
            return object;
        };

        /**
         * Converts this CaptureDisplays to JSON.
         * @function toJSON
         * @memberof hbb.CaptureDisplays
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        CaptureDisplays.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for CaptureDisplays
         * @function getTypeUrl
         * @memberof hbb.CaptureDisplays
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        CaptureDisplays.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.CaptureDisplays";
        };

        return CaptureDisplays;
    })();

    hbb.ToggleVirtualDisplay = (function() {

        /**
         * Properties of a ToggleVirtualDisplay.
         * @memberof hbb
         * @interface IToggleVirtualDisplay
         * @property {number|null} [display] ToggleVirtualDisplay display
         * @property {boolean|null} [on] ToggleVirtualDisplay on
         */

        /**
         * Constructs a new ToggleVirtualDisplay.
         * @memberof hbb
         * @classdesc Represents a ToggleVirtualDisplay.
         * @implements IToggleVirtualDisplay
         * @constructor
         * @param {hbb.IToggleVirtualDisplay=} [properties] Properties to set
         */
        function ToggleVirtualDisplay(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ToggleVirtualDisplay display.
         * @member {number} display
         * @memberof hbb.ToggleVirtualDisplay
         * @instance
         */
        ToggleVirtualDisplay.prototype.display = 0;

        /**
         * ToggleVirtualDisplay on.
         * @member {boolean} on
         * @memberof hbb.ToggleVirtualDisplay
         * @instance
         */
        ToggleVirtualDisplay.prototype.on = false;

        /**
         * Creates a new ToggleVirtualDisplay instance using the specified properties.
         * @function create
         * @memberof hbb.ToggleVirtualDisplay
         * @static
         * @param {hbb.IToggleVirtualDisplay=} [properties] Properties to set
         * @returns {hbb.ToggleVirtualDisplay} ToggleVirtualDisplay instance
         */
        ToggleVirtualDisplay.create = function create(properties) {
            return new ToggleVirtualDisplay(properties);
        };

        /**
         * Encodes the specified ToggleVirtualDisplay message. Does not implicitly {@link hbb.ToggleVirtualDisplay.verify|verify} messages.
         * @function encode
         * @memberof hbb.ToggleVirtualDisplay
         * @static
         * @param {hbb.IToggleVirtualDisplay} message ToggleVirtualDisplay message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ToggleVirtualDisplay.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.display != null && Object.hasOwnProperty.call(message, "display"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.display);
            if (message.on != null && Object.hasOwnProperty.call(message, "on"))
                writer.uint32(/* id 2, wireType 0 =*/16).bool(message.on);
            return writer;
        };

        /**
         * Encodes the specified ToggleVirtualDisplay message, length delimited. Does not implicitly {@link hbb.ToggleVirtualDisplay.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.ToggleVirtualDisplay
         * @static
         * @param {hbb.IToggleVirtualDisplay} message ToggleVirtualDisplay message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ToggleVirtualDisplay.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a ToggleVirtualDisplay message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.ToggleVirtualDisplay
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.ToggleVirtualDisplay} ToggleVirtualDisplay
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ToggleVirtualDisplay.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.ToggleVirtualDisplay();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.display = reader.int32();
                        break;
                    }
                case 2: {
                        message.on = reader.bool();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a ToggleVirtualDisplay message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.ToggleVirtualDisplay
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.ToggleVirtualDisplay} ToggleVirtualDisplay
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ToggleVirtualDisplay.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a ToggleVirtualDisplay message.
         * @function verify
         * @memberof hbb.ToggleVirtualDisplay
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ToggleVirtualDisplay.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.display != null && message.hasOwnProperty("display"))
                if (!$util.isInteger(message.display))
                    return "display: integer expected";
            if (message.on != null && message.hasOwnProperty("on"))
                if (typeof message.on !== "boolean")
                    return "on: boolean expected";
            return null;
        };

        /**
         * Creates a ToggleVirtualDisplay message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.ToggleVirtualDisplay
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.ToggleVirtualDisplay} ToggleVirtualDisplay
         */
        ToggleVirtualDisplay.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.ToggleVirtualDisplay)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.ToggleVirtualDisplay();
            if (object.display != null)
                message.display = object.display | 0;
            if (object.on != null)
                message.on = Boolean(object.on);
            return message;
        };

        /**
         * Creates a plain object from a ToggleVirtualDisplay message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.ToggleVirtualDisplay
         * @static
         * @param {hbb.ToggleVirtualDisplay} message ToggleVirtualDisplay
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ToggleVirtualDisplay.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.display = 0;
                object.on = false;
            }
            if (message.display != null && message.hasOwnProperty("display"))
                object.display = message.display;
            if (message.on != null && message.hasOwnProperty("on"))
                object.on = message.on;
            return object;
        };

        /**
         * Converts this ToggleVirtualDisplay to JSON.
         * @function toJSON
         * @memberof hbb.ToggleVirtualDisplay
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ToggleVirtualDisplay.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for ToggleVirtualDisplay
         * @function getTypeUrl
         * @memberof hbb.ToggleVirtualDisplay
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        ToggleVirtualDisplay.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.ToggleVirtualDisplay";
        };

        return ToggleVirtualDisplay;
    })();

    hbb.TogglePrivacyMode = (function() {

        /**
         * Properties of a TogglePrivacyMode.
         * @memberof hbb
         * @interface ITogglePrivacyMode
         * @property {string|null} [impl_key] TogglePrivacyMode impl_key
         * @property {boolean|null} [on] TogglePrivacyMode on
         */

        /**
         * Constructs a new TogglePrivacyMode.
         * @memberof hbb
         * @classdesc Represents a TogglePrivacyMode.
         * @implements ITogglePrivacyMode
         * @constructor
         * @param {hbb.ITogglePrivacyMode=} [properties] Properties to set
         */
        function TogglePrivacyMode(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * TogglePrivacyMode impl_key.
         * @member {string} impl_key
         * @memberof hbb.TogglePrivacyMode
         * @instance
         */
        TogglePrivacyMode.prototype.impl_key = "";

        /**
         * TogglePrivacyMode on.
         * @member {boolean} on
         * @memberof hbb.TogglePrivacyMode
         * @instance
         */
        TogglePrivacyMode.prototype.on = false;

        /**
         * Creates a new TogglePrivacyMode instance using the specified properties.
         * @function create
         * @memberof hbb.TogglePrivacyMode
         * @static
         * @param {hbb.ITogglePrivacyMode=} [properties] Properties to set
         * @returns {hbb.TogglePrivacyMode} TogglePrivacyMode instance
         */
        TogglePrivacyMode.create = function create(properties) {
            return new TogglePrivacyMode(properties);
        };

        /**
         * Encodes the specified TogglePrivacyMode message. Does not implicitly {@link hbb.TogglePrivacyMode.verify|verify} messages.
         * @function encode
         * @memberof hbb.TogglePrivacyMode
         * @static
         * @param {hbb.ITogglePrivacyMode} message TogglePrivacyMode message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        TogglePrivacyMode.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.impl_key != null && Object.hasOwnProperty.call(message, "impl_key"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.impl_key);
            if (message.on != null && Object.hasOwnProperty.call(message, "on"))
                writer.uint32(/* id 2, wireType 0 =*/16).bool(message.on);
            return writer;
        };

        /**
         * Encodes the specified TogglePrivacyMode message, length delimited. Does not implicitly {@link hbb.TogglePrivacyMode.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.TogglePrivacyMode
         * @static
         * @param {hbb.ITogglePrivacyMode} message TogglePrivacyMode message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        TogglePrivacyMode.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a TogglePrivacyMode message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.TogglePrivacyMode
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.TogglePrivacyMode} TogglePrivacyMode
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        TogglePrivacyMode.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.TogglePrivacyMode();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.impl_key = reader.string();
                        break;
                    }
                case 2: {
                        message.on = reader.bool();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a TogglePrivacyMode message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.TogglePrivacyMode
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.TogglePrivacyMode} TogglePrivacyMode
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        TogglePrivacyMode.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a TogglePrivacyMode message.
         * @function verify
         * @memberof hbb.TogglePrivacyMode
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        TogglePrivacyMode.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.impl_key != null && message.hasOwnProperty("impl_key"))
                if (!$util.isString(message.impl_key))
                    return "impl_key: string expected";
            if (message.on != null && message.hasOwnProperty("on"))
                if (typeof message.on !== "boolean")
                    return "on: boolean expected";
            return null;
        };

        /**
         * Creates a TogglePrivacyMode message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.TogglePrivacyMode
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.TogglePrivacyMode} TogglePrivacyMode
         */
        TogglePrivacyMode.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.TogglePrivacyMode)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.TogglePrivacyMode();
            if (object.impl_key != null)
                message.impl_key = String(object.impl_key);
            if (object.on != null)
                message.on = Boolean(object.on);
            return message;
        };

        /**
         * Creates a plain object from a TogglePrivacyMode message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.TogglePrivacyMode
         * @static
         * @param {hbb.TogglePrivacyMode} message TogglePrivacyMode
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        TogglePrivacyMode.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.impl_key = "";
                object.on = false;
            }
            if (message.impl_key != null && message.hasOwnProperty("impl_key"))
                object.impl_key = message.impl_key;
            if (message.on != null && message.hasOwnProperty("on"))
                object.on = message.on;
            return object;
        };

        /**
         * Converts this TogglePrivacyMode to JSON.
         * @function toJSON
         * @memberof hbb.TogglePrivacyMode
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        TogglePrivacyMode.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for TogglePrivacyMode
         * @function getTypeUrl
         * @memberof hbb.TogglePrivacyMode
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        TogglePrivacyMode.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.TogglePrivacyMode";
        };

        return TogglePrivacyMode;
    })();

    hbb.PermissionInfo = (function() {

        /**
         * Properties of a PermissionInfo.
         * @memberof hbb
         * @interface IPermissionInfo
         * @property {hbb.PermissionInfo.Permission|null} [permission] PermissionInfo permission
         * @property {boolean|null} [enabled] PermissionInfo enabled
         */

        /**
         * Constructs a new PermissionInfo.
         * @memberof hbb
         * @classdesc Represents a PermissionInfo.
         * @implements IPermissionInfo
         * @constructor
         * @param {hbb.IPermissionInfo=} [properties] Properties to set
         */
        function PermissionInfo(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * PermissionInfo permission.
         * @member {hbb.PermissionInfo.Permission} permission
         * @memberof hbb.PermissionInfo
         * @instance
         */
        PermissionInfo.prototype.permission = 0;

        /**
         * PermissionInfo enabled.
         * @member {boolean} enabled
         * @memberof hbb.PermissionInfo
         * @instance
         */
        PermissionInfo.prototype.enabled = false;

        /**
         * Creates a new PermissionInfo instance using the specified properties.
         * @function create
         * @memberof hbb.PermissionInfo
         * @static
         * @param {hbb.IPermissionInfo=} [properties] Properties to set
         * @returns {hbb.PermissionInfo} PermissionInfo instance
         */
        PermissionInfo.create = function create(properties) {
            return new PermissionInfo(properties);
        };

        /**
         * Encodes the specified PermissionInfo message. Does not implicitly {@link hbb.PermissionInfo.verify|verify} messages.
         * @function encode
         * @memberof hbb.PermissionInfo
         * @static
         * @param {hbb.IPermissionInfo} message PermissionInfo message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        PermissionInfo.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.permission != null && Object.hasOwnProperty.call(message, "permission"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.permission);
            if (message.enabled != null && Object.hasOwnProperty.call(message, "enabled"))
                writer.uint32(/* id 2, wireType 0 =*/16).bool(message.enabled);
            return writer;
        };

        /**
         * Encodes the specified PermissionInfo message, length delimited. Does not implicitly {@link hbb.PermissionInfo.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.PermissionInfo
         * @static
         * @param {hbb.IPermissionInfo} message PermissionInfo message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        PermissionInfo.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a PermissionInfo message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.PermissionInfo
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.PermissionInfo} PermissionInfo
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        PermissionInfo.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.PermissionInfo();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.permission = reader.int32();
                        break;
                    }
                case 2: {
                        message.enabled = reader.bool();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a PermissionInfo message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.PermissionInfo
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.PermissionInfo} PermissionInfo
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        PermissionInfo.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a PermissionInfo message.
         * @function verify
         * @memberof hbb.PermissionInfo
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        PermissionInfo.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.permission != null && message.hasOwnProperty("permission"))
                switch (message.permission) {
                default:
                    return "permission: enum value expected";
                case 0:
                case 2:
                case 3:
                case 4:
                case 5:
                case 6:
                case 7:
                case 8:
                    break;
                }
            if (message.enabled != null && message.hasOwnProperty("enabled"))
                if (typeof message.enabled !== "boolean")
                    return "enabled: boolean expected";
            return null;
        };

        /**
         * Creates a PermissionInfo message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.PermissionInfo
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.PermissionInfo} PermissionInfo
         */
        PermissionInfo.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.PermissionInfo)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.PermissionInfo();
            switch (object.permission) {
            default:
                if (typeof object.permission === "number") {
                    message.permission = object.permission;
                    break;
                }
                break;
            case "Keyboard":
            case 0:
                message.permission = 0;
                break;
            case "Clipboard":
            case 2:
                message.permission = 2;
                break;
            case "Audio":
            case 3:
                message.permission = 3;
                break;
            case "File":
            case 4:
                message.permission = 4;
                break;
            case "Restart":
            case 5:
                message.permission = 5;
                break;
            case "Recording":
            case 6:
                message.permission = 6;
                break;
            case "BlockInput":
            case 7:
                message.permission = 7;
                break;
            case "Camera":
            case 8:
                message.permission = 8;
                break;
            }
            if (object.enabled != null)
                message.enabled = Boolean(object.enabled);
            return message;
        };

        /**
         * Creates a plain object from a PermissionInfo message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.PermissionInfo
         * @static
         * @param {hbb.PermissionInfo} message PermissionInfo
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        PermissionInfo.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.permission = options.enums === String ? "Keyboard" : 0;
                object.enabled = false;
            }
            if (message.permission != null && message.hasOwnProperty("permission"))
                object.permission = options.enums === String ? $root.hbb.PermissionInfo.Permission[message.permission] === undefined ? message.permission : $root.hbb.PermissionInfo.Permission[message.permission] : message.permission;
            if (message.enabled != null && message.hasOwnProperty("enabled"))
                object.enabled = message.enabled;
            return object;
        };

        /**
         * Converts this PermissionInfo to JSON.
         * @function toJSON
         * @memberof hbb.PermissionInfo
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        PermissionInfo.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for PermissionInfo
         * @function getTypeUrl
         * @memberof hbb.PermissionInfo
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        PermissionInfo.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.PermissionInfo";
        };

        /**
         * Permission enum.
         * @name hbb.PermissionInfo.Permission
         * @enum {number}
         * @property {number} Keyboard=0 Keyboard value
         * @property {number} Clipboard=2 Clipboard value
         * @property {number} Audio=3 Audio value
         * @property {number} File=4 File value
         * @property {number} Restart=5 Restart value
         * @property {number} Recording=6 Recording value
         * @property {number} BlockInput=7 BlockInput value
         * @property {number} Camera=8 Camera value
         */
        PermissionInfo.Permission = (function() {
            const valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "Keyboard"] = 0;
            values[valuesById[2] = "Clipboard"] = 2;
            values[valuesById[3] = "Audio"] = 3;
            values[valuesById[4] = "File"] = 4;
            values[valuesById[5] = "Restart"] = 5;
            values[valuesById[6] = "Recording"] = 6;
            values[valuesById[7] = "BlockInput"] = 7;
            values[valuesById[8] = "Camera"] = 8;
            return values;
        })();

        return PermissionInfo;
    })();

    /**
     * ImageQuality enum.
     * @name hbb.ImageQuality
     * @enum {number}
     * @property {number} NotSet=0 NotSet value
     * @property {number} Low=2 Low value
     * @property {number} Balanced=3 Balanced value
     * @property {number} Best=4 Best value
     */
    hbb.ImageQuality = (function() {
        const valuesById = {}, values = Object.create(valuesById);
        values[valuesById[0] = "NotSet"] = 0;
        values[valuesById[2] = "Low"] = 2;
        values[valuesById[3] = "Balanced"] = 3;
        values[valuesById[4] = "Best"] = 4;
        return values;
    })();

    hbb.SupportedDecoding = (function() {

        /**
         * Properties of a SupportedDecoding.
         * @memberof hbb
         * @interface ISupportedDecoding
         * @property {number|null} [ability_vp9] SupportedDecoding ability_vp9
         * @property {number|null} [ability_h264] SupportedDecoding ability_h264
         * @property {number|null} [ability_h265] SupportedDecoding ability_h265
         * @property {hbb.SupportedDecoding.PreferCodec|null} [prefer] SupportedDecoding prefer
         * @property {number|null} [ability_vp8] SupportedDecoding ability_vp8
         * @property {number|null} [ability_av1] SupportedDecoding ability_av1
         * @property {hbb.ICodecAbility|null} [i444] SupportedDecoding i444
         * @property {hbb.Chroma|null} [prefer_chroma] SupportedDecoding prefer_chroma
         */

        /**
         * Constructs a new SupportedDecoding.
         * @memberof hbb
         * @classdesc Represents a SupportedDecoding.
         * @implements ISupportedDecoding
         * @constructor
         * @param {hbb.ISupportedDecoding=} [properties] Properties to set
         */
        function SupportedDecoding(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * SupportedDecoding ability_vp9.
         * @member {number} ability_vp9
         * @memberof hbb.SupportedDecoding
         * @instance
         */
        SupportedDecoding.prototype.ability_vp9 = 0;

        /**
         * SupportedDecoding ability_h264.
         * @member {number} ability_h264
         * @memberof hbb.SupportedDecoding
         * @instance
         */
        SupportedDecoding.prototype.ability_h264 = 0;

        /**
         * SupportedDecoding ability_h265.
         * @member {number} ability_h265
         * @memberof hbb.SupportedDecoding
         * @instance
         */
        SupportedDecoding.prototype.ability_h265 = 0;

        /**
         * SupportedDecoding prefer.
         * @member {hbb.SupportedDecoding.PreferCodec} prefer
         * @memberof hbb.SupportedDecoding
         * @instance
         */
        SupportedDecoding.prototype.prefer = 0;

        /**
         * SupportedDecoding ability_vp8.
         * @member {number} ability_vp8
         * @memberof hbb.SupportedDecoding
         * @instance
         */
        SupportedDecoding.prototype.ability_vp8 = 0;

        /**
         * SupportedDecoding ability_av1.
         * @member {number} ability_av1
         * @memberof hbb.SupportedDecoding
         * @instance
         */
        SupportedDecoding.prototype.ability_av1 = 0;

        /**
         * SupportedDecoding i444.
         * @member {hbb.ICodecAbility|null|undefined} i444
         * @memberof hbb.SupportedDecoding
         * @instance
         */
        SupportedDecoding.prototype.i444 = null;

        /**
         * SupportedDecoding prefer_chroma.
         * @member {hbb.Chroma} prefer_chroma
         * @memberof hbb.SupportedDecoding
         * @instance
         */
        SupportedDecoding.prototype.prefer_chroma = 0;

        /**
         * Creates a new SupportedDecoding instance using the specified properties.
         * @function create
         * @memberof hbb.SupportedDecoding
         * @static
         * @param {hbb.ISupportedDecoding=} [properties] Properties to set
         * @returns {hbb.SupportedDecoding} SupportedDecoding instance
         */
        SupportedDecoding.create = function create(properties) {
            return new SupportedDecoding(properties);
        };

        /**
         * Encodes the specified SupportedDecoding message. Does not implicitly {@link hbb.SupportedDecoding.verify|verify} messages.
         * @function encode
         * @memberof hbb.SupportedDecoding
         * @static
         * @param {hbb.ISupportedDecoding} message SupportedDecoding message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SupportedDecoding.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.ability_vp9 != null && Object.hasOwnProperty.call(message, "ability_vp9"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.ability_vp9);
            if (message.ability_h264 != null && Object.hasOwnProperty.call(message, "ability_h264"))
                writer.uint32(/* id 2, wireType 0 =*/16).int32(message.ability_h264);
            if (message.ability_h265 != null && Object.hasOwnProperty.call(message, "ability_h265"))
                writer.uint32(/* id 3, wireType 0 =*/24).int32(message.ability_h265);
            if (message.prefer != null && Object.hasOwnProperty.call(message, "prefer"))
                writer.uint32(/* id 4, wireType 0 =*/32).int32(message.prefer);
            if (message.ability_vp8 != null && Object.hasOwnProperty.call(message, "ability_vp8"))
                writer.uint32(/* id 5, wireType 0 =*/40).int32(message.ability_vp8);
            if (message.ability_av1 != null && Object.hasOwnProperty.call(message, "ability_av1"))
                writer.uint32(/* id 6, wireType 0 =*/48).int32(message.ability_av1);
            if (message.i444 != null && Object.hasOwnProperty.call(message, "i444"))
                $root.hbb.CodecAbility.encode(message.i444, writer.uint32(/* id 7, wireType 2 =*/58).fork()).ldelim();
            if (message.prefer_chroma != null && Object.hasOwnProperty.call(message, "prefer_chroma"))
                writer.uint32(/* id 8, wireType 0 =*/64).int32(message.prefer_chroma);
            return writer;
        };

        /**
         * Encodes the specified SupportedDecoding message, length delimited. Does not implicitly {@link hbb.SupportedDecoding.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.SupportedDecoding
         * @static
         * @param {hbb.ISupportedDecoding} message SupportedDecoding message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SupportedDecoding.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a SupportedDecoding message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.SupportedDecoding
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.SupportedDecoding} SupportedDecoding
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SupportedDecoding.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.SupportedDecoding();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.ability_vp9 = reader.int32();
                        break;
                    }
                case 2: {
                        message.ability_h264 = reader.int32();
                        break;
                    }
                case 3: {
                        message.ability_h265 = reader.int32();
                        break;
                    }
                case 4: {
                        message.prefer = reader.int32();
                        break;
                    }
                case 5: {
                        message.ability_vp8 = reader.int32();
                        break;
                    }
                case 6: {
                        message.ability_av1 = reader.int32();
                        break;
                    }
                case 7: {
                        message.i444 = $root.hbb.CodecAbility.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 8: {
                        message.prefer_chroma = reader.int32();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a SupportedDecoding message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.SupportedDecoding
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.SupportedDecoding} SupportedDecoding
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SupportedDecoding.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a SupportedDecoding message.
         * @function verify
         * @memberof hbb.SupportedDecoding
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        SupportedDecoding.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.ability_vp9 != null && message.hasOwnProperty("ability_vp9"))
                if (!$util.isInteger(message.ability_vp9))
                    return "ability_vp9: integer expected";
            if (message.ability_h264 != null && message.hasOwnProperty("ability_h264"))
                if (!$util.isInteger(message.ability_h264))
                    return "ability_h264: integer expected";
            if (message.ability_h265 != null && message.hasOwnProperty("ability_h265"))
                if (!$util.isInteger(message.ability_h265))
                    return "ability_h265: integer expected";
            if (message.prefer != null && message.hasOwnProperty("prefer"))
                switch (message.prefer) {
                default:
                    return "prefer: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                case 4:
                case 5:
                    break;
                }
            if (message.ability_vp8 != null && message.hasOwnProperty("ability_vp8"))
                if (!$util.isInteger(message.ability_vp8))
                    return "ability_vp8: integer expected";
            if (message.ability_av1 != null && message.hasOwnProperty("ability_av1"))
                if (!$util.isInteger(message.ability_av1))
                    return "ability_av1: integer expected";
            if (message.i444 != null && message.hasOwnProperty("i444")) {
                let error = $root.hbb.CodecAbility.verify(message.i444, long + 1);
                if (error)
                    return "i444." + error;
            }
            if (message.prefer_chroma != null && message.hasOwnProperty("prefer_chroma"))
                switch (message.prefer_chroma) {
                default:
                    return "prefer_chroma: enum value expected";
                case 0:
                case 1:
                    break;
                }
            return null;
        };

        /**
         * Creates a SupportedDecoding message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.SupportedDecoding
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.SupportedDecoding} SupportedDecoding
         */
        SupportedDecoding.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.SupportedDecoding)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.SupportedDecoding();
            if (object.ability_vp9 != null)
                message.ability_vp9 = object.ability_vp9 | 0;
            if (object.ability_h264 != null)
                message.ability_h264 = object.ability_h264 | 0;
            if (object.ability_h265 != null)
                message.ability_h265 = object.ability_h265 | 0;
            switch (object.prefer) {
            default:
                if (typeof object.prefer === "number") {
                    message.prefer = object.prefer;
                    break;
                }
                break;
            case "Auto":
            case 0:
                message.prefer = 0;
                break;
            case "VP9":
            case 1:
                message.prefer = 1;
                break;
            case "H264":
            case 2:
                message.prefer = 2;
                break;
            case "H265":
            case 3:
                message.prefer = 3;
                break;
            case "VP8":
            case 4:
                message.prefer = 4;
                break;
            case "AV1":
            case 5:
                message.prefer = 5;
                break;
            }
            if (object.ability_vp8 != null)
                message.ability_vp8 = object.ability_vp8 | 0;
            if (object.ability_av1 != null)
                message.ability_av1 = object.ability_av1 | 0;
            if (object.i444 != null) {
                if (typeof object.i444 !== "object")
                    throw TypeError(".hbb.SupportedDecoding.i444: object expected");
                message.i444 = $root.hbb.CodecAbility.fromObject(object.i444, long + 1);
            }
            switch (object.prefer_chroma) {
            default:
                if (typeof object.prefer_chroma === "number") {
                    message.prefer_chroma = object.prefer_chroma;
                    break;
                }
                break;
            case "I420":
            case 0:
                message.prefer_chroma = 0;
                break;
            case "I444":
            case 1:
                message.prefer_chroma = 1;
                break;
            }
            return message;
        };

        /**
         * Creates a plain object from a SupportedDecoding message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.SupportedDecoding
         * @static
         * @param {hbb.SupportedDecoding} message SupportedDecoding
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        SupportedDecoding.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.ability_vp9 = 0;
                object.ability_h264 = 0;
                object.ability_h265 = 0;
                object.prefer = options.enums === String ? "Auto" : 0;
                object.ability_vp8 = 0;
                object.ability_av1 = 0;
                object.i444 = null;
                object.prefer_chroma = options.enums === String ? "I420" : 0;
            }
            if (message.ability_vp9 != null && message.hasOwnProperty("ability_vp9"))
                object.ability_vp9 = message.ability_vp9;
            if (message.ability_h264 != null && message.hasOwnProperty("ability_h264"))
                object.ability_h264 = message.ability_h264;
            if (message.ability_h265 != null && message.hasOwnProperty("ability_h265"))
                object.ability_h265 = message.ability_h265;
            if (message.prefer != null && message.hasOwnProperty("prefer"))
                object.prefer = options.enums === String ? $root.hbb.SupportedDecoding.PreferCodec[message.prefer] === undefined ? message.prefer : $root.hbb.SupportedDecoding.PreferCodec[message.prefer] : message.prefer;
            if (message.ability_vp8 != null && message.hasOwnProperty("ability_vp8"))
                object.ability_vp8 = message.ability_vp8;
            if (message.ability_av1 != null && message.hasOwnProperty("ability_av1"))
                object.ability_av1 = message.ability_av1;
            if (message.i444 != null && message.hasOwnProperty("i444"))
                object.i444 = $root.hbb.CodecAbility.toObject(message.i444, options);
            if (message.prefer_chroma != null && message.hasOwnProperty("prefer_chroma"))
                object.prefer_chroma = options.enums === String ? $root.hbb.Chroma[message.prefer_chroma] === undefined ? message.prefer_chroma : $root.hbb.Chroma[message.prefer_chroma] : message.prefer_chroma;
            return object;
        };

        /**
         * Converts this SupportedDecoding to JSON.
         * @function toJSON
         * @memberof hbb.SupportedDecoding
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        SupportedDecoding.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for SupportedDecoding
         * @function getTypeUrl
         * @memberof hbb.SupportedDecoding
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        SupportedDecoding.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.SupportedDecoding";
        };

        /**
         * PreferCodec enum.
         * @name hbb.SupportedDecoding.PreferCodec
         * @enum {number}
         * @property {number} Auto=0 Auto value
         * @property {number} VP9=1 VP9 value
         * @property {number} H264=2 H264 value
         * @property {number} H265=3 H265 value
         * @property {number} VP8=4 VP8 value
         * @property {number} AV1=5 AV1 value
         */
        SupportedDecoding.PreferCodec = (function() {
            const valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "Auto"] = 0;
            values[valuesById[1] = "VP9"] = 1;
            values[valuesById[2] = "H264"] = 2;
            values[valuesById[3] = "H265"] = 3;
            values[valuesById[4] = "VP8"] = 4;
            values[valuesById[5] = "AV1"] = 5;
            return values;
        })();

        return SupportedDecoding;
    })();

    hbb.OptionMessage = (function() {

        /**
         * Properties of an OptionMessage.
         * @memberof hbb
         * @interface IOptionMessage
         * @property {hbb.ImageQuality|null} [image_quality] OptionMessage image_quality
         * @property {hbb.OptionMessage.BoolOption|null} [lock_after_session_end] OptionMessage lock_after_session_end
         * @property {hbb.OptionMessage.BoolOption|null} [show_remote_cursor] OptionMessage show_remote_cursor
         * @property {hbb.OptionMessage.BoolOption|null} [privacy_mode] OptionMessage privacy_mode
         * @property {hbb.OptionMessage.BoolOption|null} [block_input] OptionMessage block_input
         * @property {number|null} [custom_image_quality] OptionMessage custom_image_quality
         * @property {hbb.OptionMessage.BoolOption|null} [disable_audio] OptionMessage disable_audio
         * @property {hbb.OptionMessage.BoolOption|null} [disable_clipboard] OptionMessage disable_clipboard
         * @property {hbb.OptionMessage.BoolOption|null} [enable_file_transfer] OptionMessage enable_file_transfer
         * @property {hbb.ISupportedDecoding|null} [supported_decoding] OptionMessage supported_decoding
         * @property {number|null} [custom_fps] OptionMessage custom_fps
         * @property {hbb.OptionMessage.BoolOption|null} [disable_keyboard] OptionMessage disable_keyboard
         * @property {hbb.OptionMessage.BoolOption|null} [follow_remote_cursor] OptionMessage follow_remote_cursor
         * @property {hbb.OptionMessage.BoolOption|null} [follow_remote_window] OptionMessage follow_remote_window
         * @property {hbb.OptionMessage.BoolOption|null} [disable_camera] OptionMessage disable_camera
         */

        /**
         * Constructs a new OptionMessage.
         * @memberof hbb
         * @classdesc Represents an OptionMessage.
         * @implements IOptionMessage
         * @constructor
         * @param {hbb.IOptionMessage=} [properties] Properties to set
         */
        function OptionMessage(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * OptionMessage image_quality.
         * @member {hbb.ImageQuality} image_quality
         * @memberof hbb.OptionMessage
         * @instance
         */
        OptionMessage.prototype.image_quality = 0;

        /**
         * OptionMessage lock_after_session_end.
         * @member {hbb.OptionMessage.BoolOption} lock_after_session_end
         * @memberof hbb.OptionMessage
         * @instance
         */
        OptionMessage.prototype.lock_after_session_end = 0;

        /**
         * OptionMessage show_remote_cursor.
         * @member {hbb.OptionMessage.BoolOption} show_remote_cursor
         * @memberof hbb.OptionMessage
         * @instance
         */
        OptionMessage.prototype.show_remote_cursor = 0;

        /**
         * OptionMessage privacy_mode.
         * @member {hbb.OptionMessage.BoolOption} privacy_mode
         * @memberof hbb.OptionMessage
         * @instance
         */
        OptionMessage.prototype.privacy_mode = 0;

        /**
         * OptionMessage block_input.
         * @member {hbb.OptionMessage.BoolOption} block_input
         * @memberof hbb.OptionMessage
         * @instance
         */
        OptionMessage.prototype.block_input = 0;

        /**
         * OptionMessage custom_image_quality.
         * @member {number} custom_image_quality
         * @memberof hbb.OptionMessage
         * @instance
         */
        OptionMessage.prototype.custom_image_quality = 0;

        /**
         * OptionMessage disable_audio.
         * @member {hbb.OptionMessage.BoolOption} disable_audio
         * @memberof hbb.OptionMessage
         * @instance
         */
        OptionMessage.prototype.disable_audio = 0;

        /**
         * OptionMessage disable_clipboard.
         * @member {hbb.OptionMessage.BoolOption} disable_clipboard
         * @memberof hbb.OptionMessage
         * @instance
         */
        OptionMessage.prototype.disable_clipboard = 0;

        /**
         * OptionMessage enable_file_transfer.
         * @member {hbb.OptionMessage.BoolOption} enable_file_transfer
         * @memberof hbb.OptionMessage
         * @instance
         */
        OptionMessage.prototype.enable_file_transfer = 0;

        /**
         * OptionMessage supported_decoding.
         * @member {hbb.ISupportedDecoding|null|undefined} supported_decoding
         * @memberof hbb.OptionMessage
         * @instance
         */
        OptionMessage.prototype.supported_decoding = null;

        /**
         * OptionMessage custom_fps.
         * @member {number} custom_fps
         * @memberof hbb.OptionMessage
         * @instance
         */
        OptionMessage.prototype.custom_fps = 0;

        /**
         * OptionMessage disable_keyboard.
         * @member {hbb.OptionMessage.BoolOption} disable_keyboard
         * @memberof hbb.OptionMessage
         * @instance
         */
        OptionMessage.prototype.disable_keyboard = 0;

        /**
         * OptionMessage follow_remote_cursor.
         * @member {hbb.OptionMessage.BoolOption} follow_remote_cursor
         * @memberof hbb.OptionMessage
         * @instance
         */
        OptionMessage.prototype.follow_remote_cursor = 0;

        /**
         * OptionMessage follow_remote_window.
         * @member {hbb.OptionMessage.BoolOption} follow_remote_window
         * @memberof hbb.OptionMessage
         * @instance
         */
        OptionMessage.prototype.follow_remote_window = 0;

        /**
         * OptionMessage disable_camera.
         * @member {hbb.OptionMessage.BoolOption} disable_camera
         * @memberof hbb.OptionMessage
         * @instance
         */
        OptionMessage.prototype.disable_camera = 0;

        /**
         * Creates a new OptionMessage instance using the specified properties.
         * @function create
         * @memberof hbb.OptionMessage
         * @static
         * @param {hbb.IOptionMessage=} [properties] Properties to set
         * @returns {hbb.OptionMessage} OptionMessage instance
         */
        OptionMessage.create = function create(properties) {
            return new OptionMessage(properties);
        };

        /**
         * Encodes the specified OptionMessage message. Does not implicitly {@link hbb.OptionMessage.verify|verify} messages.
         * @function encode
         * @memberof hbb.OptionMessage
         * @static
         * @param {hbb.IOptionMessage} message OptionMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        OptionMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.image_quality != null && Object.hasOwnProperty.call(message, "image_quality"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.image_quality);
            if (message.lock_after_session_end != null && Object.hasOwnProperty.call(message, "lock_after_session_end"))
                writer.uint32(/* id 2, wireType 0 =*/16).int32(message.lock_after_session_end);
            if (message.show_remote_cursor != null && Object.hasOwnProperty.call(message, "show_remote_cursor"))
                writer.uint32(/* id 3, wireType 0 =*/24).int32(message.show_remote_cursor);
            if (message.privacy_mode != null && Object.hasOwnProperty.call(message, "privacy_mode"))
                writer.uint32(/* id 4, wireType 0 =*/32).int32(message.privacy_mode);
            if (message.block_input != null && Object.hasOwnProperty.call(message, "block_input"))
                writer.uint32(/* id 5, wireType 0 =*/40).int32(message.block_input);
            if (message.custom_image_quality != null && Object.hasOwnProperty.call(message, "custom_image_quality"))
                writer.uint32(/* id 6, wireType 0 =*/48).int32(message.custom_image_quality);
            if (message.disable_audio != null && Object.hasOwnProperty.call(message, "disable_audio"))
                writer.uint32(/* id 7, wireType 0 =*/56).int32(message.disable_audio);
            if (message.disable_clipboard != null && Object.hasOwnProperty.call(message, "disable_clipboard"))
                writer.uint32(/* id 8, wireType 0 =*/64).int32(message.disable_clipboard);
            if (message.enable_file_transfer != null && Object.hasOwnProperty.call(message, "enable_file_transfer"))
                writer.uint32(/* id 9, wireType 0 =*/72).int32(message.enable_file_transfer);
            if (message.supported_decoding != null && Object.hasOwnProperty.call(message, "supported_decoding"))
                $root.hbb.SupportedDecoding.encode(message.supported_decoding, writer.uint32(/* id 10, wireType 2 =*/82).fork()).ldelim();
            if (message.custom_fps != null && Object.hasOwnProperty.call(message, "custom_fps"))
                writer.uint32(/* id 11, wireType 0 =*/88).int32(message.custom_fps);
            if (message.disable_keyboard != null && Object.hasOwnProperty.call(message, "disable_keyboard"))
                writer.uint32(/* id 12, wireType 0 =*/96).int32(message.disable_keyboard);
            if (message.follow_remote_cursor != null && Object.hasOwnProperty.call(message, "follow_remote_cursor"))
                writer.uint32(/* id 15, wireType 0 =*/120).int32(message.follow_remote_cursor);
            if (message.follow_remote_window != null && Object.hasOwnProperty.call(message, "follow_remote_window"))
                writer.uint32(/* id 16, wireType 0 =*/128).int32(message.follow_remote_window);
            if (message.disable_camera != null && Object.hasOwnProperty.call(message, "disable_camera"))
                writer.uint32(/* id 17, wireType 0 =*/136).int32(message.disable_camera);
            return writer;
        };

        /**
         * Encodes the specified OptionMessage message, length delimited. Does not implicitly {@link hbb.OptionMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.OptionMessage
         * @static
         * @param {hbb.IOptionMessage} message OptionMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        OptionMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an OptionMessage message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.OptionMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.OptionMessage} OptionMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        OptionMessage.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.OptionMessage();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.image_quality = reader.int32();
                        break;
                    }
                case 2: {
                        message.lock_after_session_end = reader.int32();
                        break;
                    }
                case 3: {
                        message.show_remote_cursor = reader.int32();
                        break;
                    }
                case 4: {
                        message.privacy_mode = reader.int32();
                        break;
                    }
                case 5: {
                        message.block_input = reader.int32();
                        break;
                    }
                case 6: {
                        message.custom_image_quality = reader.int32();
                        break;
                    }
                case 7: {
                        message.disable_audio = reader.int32();
                        break;
                    }
                case 8: {
                        message.disable_clipboard = reader.int32();
                        break;
                    }
                case 9: {
                        message.enable_file_transfer = reader.int32();
                        break;
                    }
                case 10: {
                        message.supported_decoding = $root.hbb.SupportedDecoding.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 11: {
                        message.custom_fps = reader.int32();
                        break;
                    }
                case 12: {
                        message.disable_keyboard = reader.int32();
                        break;
                    }
                case 15: {
                        message.follow_remote_cursor = reader.int32();
                        break;
                    }
                case 16: {
                        message.follow_remote_window = reader.int32();
                        break;
                    }
                case 17: {
                        message.disable_camera = reader.int32();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an OptionMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.OptionMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.OptionMessage} OptionMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        OptionMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an OptionMessage message.
         * @function verify
         * @memberof hbb.OptionMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        OptionMessage.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.image_quality != null && message.hasOwnProperty("image_quality"))
                switch (message.image_quality) {
                default:
                    return "image_quality: enum value expected";
                case 0:
                case 2:
                case 3:
                case 4:
                    break;
                }
            if (message.lock_after_session_end != null && message.hasOwnProperty("lock_after_session_end"))
                switch (message.lock_after_session_end) {
                default:
                    return "lock_after_session_end: enum value expected";
                case 0:
                case 1:
                case 2:
                    break;
                }
            if (message.show_remote_cursor != null && message.hasOwnProperty("show_remote_cursor"))
                switch (message.show_remote_cursor) {
                default:
                    return "show_remote_cursor: enum value expected";
                case 0:
                case 1:
                case 2:
                    break;
                }
            if (message.privacy_mode != null && message.hasOwnProperty("privacy_mode"))
                switch (message.privacy_mode) {
                default:
                    return "privacy_mode: enum value expected";
                case 0:
                case 1:
                case 2:
                    break;
                }
            if (message.block_input != null && message.hasOwnProperty("block_input"))
                switch (message.block_input) {
                default:
                    return "block_input: enum value expected";
                case 0:
                case 1:
                case 2:
                    break;
                }
            if (message.custom_image_quality != null && message.hasOwnProperty("custom_image_quality"))
                if (!$util.isInteger(message.custom_image_quality))
                    return "custom_image_quality: integer expected";
            if (message.disable_audio != null && message.hasOwnProperty("disable_audio"))
                switch (message.disable_audio) {
                default:
                    return "disable_audio: enum value expected";
                case 0:
                case 1:
                case 2:
                    break;
                }
            if (message.disable_clipboard != null && message.hasOwnProperty("disable_clipboard"))
                switch (message.disable_clipboard) {
                default:
                    return "disable_clipboard: enum value expected";
                case 0:
                case 1:
                case 2:
                    break;
                }
            if (message.enable_file_transfer != null && message.hasOwnProperty("enable_file_transfer"))
                switch (message.enable_file_transfer) {
                default:
                    return "enable_file_transfer: enum value expected";
                case 0:
                case 1:
                case 2:
                    break;
                }
            if (message.supported_decoding != null && message.hasOwnProperty("supported_decoding")) {
                let error = $root.hbb.SupportedDecoding.verify(message.supported_decoding, long + 1);
                if (error)
                    return "supported_decoding." + error;
            }
            if (message.custom_fps != null && message.hasOwnProperty("custom_fps"))
                if (!$util.isInteger(message.custom_fps))
                    return "custom_fps: integer expected";
            if (message.disable_keyboard != null && message.hasOwnProperty("disable_keyboard"))
                switch (message.disable_keyboard) {
                default:
                    return "disable_keyboard: enum value expected";
                case 0:
                case 1:
                case 2:
                    break;
                }
            if (message.follow_remote_cursor != null && message.hasOwnProperty("follow_remote_cursor"))
                switch (message.follow_remote_cursor) {
                default:
                    return "follow_remote_cursor: enum value expected";
                case 0:
                case 1:
                case 2:
                    break;
                }
            if (message.follow_remote_window != null && message.hasOwnProperty("follow_remote_window"))
                switch (message.follow_remote_window) {
                default:
                    return "follow_remote_window: enum value expected";
                case 0:
                case 1:
                case 2:
                    break;
                }
            if (message.disable_camera != null && message.hasOwnProperty("disable_camera"))
                switch (message.disable_camera) {
                default:
                    return "disable_camera: enum value expected";
                case 0:
                case 1:
                case 2:
                    break;
                }
            return null;
        };

        /**
         * Creates an OptionMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.OptionMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.OptionMessage} OptionMessage
         */
        OptionMessage.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.OptionMessage)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.OptionMessage();
            switch (object.image_quality) {
            default:
                if (typeof object.image_quality === "number") {
                    message.image_quality = object.image_quality;
                    break;
                }
                break;
            case "NotSet":
            case 0:
                message.image_quality = 0;
                break;
            case "Low":
            case 2:
                message.image_quality = 2;
                break;
            case "Balanced":
            case 3:
                message.image_quality = 3;
                break;
            case "Best":
            case 4:
                message.image_quality = 4;
                break;
            }
            switch (object.lock_after_session_end) {
            default:
                if (typeof object.lock_after_session_end === "number") {
                    message.lock_after_session_end = object.lock_after_session_end;
                    break;
                }
                break;
            case "NotSet":
            case 0:
                message.lock_after_session_end = 0;
                break;
            case "No":
            case 1:
                message.lock_after_session_end = 1;
                break;
            case "Yes":
            case 2:
                message.lock_after_session_end = 2;
                break;
            }
            switch (object.show_remote_cursor) {
            default:
                if (typeof object.show_remote_cursor === "number") {
                    message.show_remote_cursor = object.show_remote_cursor;
                    break;
                }
                break;
            case "NotSet":
            case 0:
                message.show_remote_cursor = 0;
                break;
            case "No":
            case 1:
                message.show_remote_cursor = 1;
                break;
            case "Yes":
            case 2:
                message.show_remote_cursor = 2;
                break;
            }
            switch (object.privacy_mode) {
            default:
                if (typeof object.privacy_mode === "number") {
                    message.privacy_mode = object.privacy_mode;
                    break;
                }
                break;
            case "NotSet":
            case 0:
                message.privacy_mode = 0;
                break;
            case "No":
            case 1:
                message.privacy_mode = 1;
                break;
            case "Yes":
            case 2:
                message.privacy_mode = 2;
                break;
            }
            switch (object.block_input) {
            default:
                if (typeof object.block_input === "number") {
                    message.block_input = object.block_input;
                    break;
                }
                break;
            case "NotSet":
            case 0:
                message.block_input = 0;
                break;
            case "No":
            case 1:
                message.block_input = 1;
                break;
            case "Yes":
            case 2:
                message.block_input = 2;
                break;
            }
            if (object.custom_image_quality != null)
                message.custom_image_quality = object.custom_image_quality | 0;
            switch (object.disable_audio) {
            default:
                if (typeof object.disable_audio === "number") {
                    message.disable_audio = object.disable_audio;
                    break;
                }
                break;
            case "NotSet":
            case 0:
                message.disable_audio = 0;
                break;
            case "No":
            case 1:
                message.disable_audio = 1;
                break;
            case "Yes":
            case 2:
                message.disable_audio = 2;
                break;
            }
            switch (object.disable_clipboard) {
            default:
                if (typeof object.disable_clipboard === "number") {
                    message.disable_clipboard = object.disable_clipboard;
                    break;
                }
                break;
            case "NotSet":
            case 0:
                message.disable_clipboard = 0;
                break;
            case "No":
            case 1:
                message.disable_clipboard = 1;
                break;
            case "Yes":
            case 2:
                message.disable_clipboard = 2;
                break;
            }
            switch (object.enable_file_transfer) {
            default:
                if (typeof object.enable_file_transfer === "number") {
                    message.enable_file_transfer = object.enable_file_transfer;
                    break;
                }
                break;
            case "NotSet":
            case 0:
                message.enable_file_transfer = 0;
                break;
            case "No":
            case 1:
                message.enable_file_transfer = 1;
                break;
            case "Yes":
            case 2:
                message.enable_file_transfer = 2;
                break;
            }
            if (object.supported_decoding != null) {
                if (typeof object.supported_decoding !== "object")
                    throw TypeError(".hbb.OptionMessage.supported_decoding: object expected");
                message.supported_decoding = $root.hbb.SupportedDecoding.fromObject(object.supported_decoding, long + 1);
            }
            if (object.custom_fps != null)
                message.custom_fps = object.custom_fps | 0;
            switch (object.disable_keyboard) {
            default:
                if (typeof object.disable_keyboard === "number") {
                    message.disable_keyboard = object.disable_keyboard;
                    break;
                }
                break;
            case "NotSet":
            case 0:
                message.disable_keyboard = 0;
                break;
            case "No":
            case 1:
                message.disable_keyboard = 1;
                break;
            case "Yes":
            case 2:
                message.disable_keyboard = 2;
                break;
            }
            switch (object.follow_remote_cursor) {
            default:
                if (typeof object.follow_remote_cursor === "number") {
                    message.follow_remote_cursor = object.follow_remote_cursor;
                    break;
                }
                break;
            case "NotSet":
            case 0:
                message.follow_remote_cursor = 0;
                break;
            case "No":
            case 1:
                message.follow_remote_cursor = 1;
                break;
            case "Yes":
            case 2:
                message.follow_remote_cursor = 2;
                break;
            }
            switch (object.follow_remote_window) {
            default:
                if (typeof object.follow_remote_window === "number") {
                    message.follow_remote_window = object.follow_remote_window;
                    break;
                }
                break;
            case "NotSet":
            case 0:
                message.follow_remote_window = 0;
                break;
            case "No":
            case 1:
                message.follow_remote_window = 1;
                break;
            case "Yes":
            case 2:
                message.follow_remote_window = 2;
                break;
            }
            switch (object.disable_camera) {
            default:
                if (typeof object.disable_camera === "number") {
                    message.disable_camera = object.disable_camera;
                    break;
                }
                break;
            case "NotSet":
            case 0:
                message.disable_camera = 0;
                break;
            case "No":
            case 1:
                message.disable_camera = 1;
                break;
            case "Yes":
            case 2:
                message.disable_camera = 2;
                break;
            }
            return message;
        };

        /**
         * Creates a plain object from an OptionMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.OptionMessage
         * @static
         * @param {hbb.OptionMessage} message OptionMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        OptionMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.image_quality = options.enums === String ? "NotSet" : 0;
                object.lock_after_session_end = options.enums === String ? "NotSet" : 0;
                object.show_remote_cursor = options.enums === String ? "NotSet" : 0;
                object.privacy_mode = options.enums === String ? "NotSet" : 0;
                object.block_input = options.enums === String ? "NotSet" : 0;
                object.custom_image_quality = 0;
                object.disable_audio = options.enums === String ? "NotSet" : 0;
                object.disable_clipboard = options.enums === String ? "NotSet" : 0;
                object.enable_file_transfer = options.enums === String ? "NotSet" : 0;
                object.supported_decoding = null;
                object.custom_fps = 0;
                object.disable_keyboard = options.enums === String ? "NotSet" : 0;
                object.follow_remote_cursor = options.enums === String ? "NotSet" : 0;
                object.follow_remote_window = options.enums === String ? "NotSet" : 0;
                object.disable_camera = options.enums === String ? "NotSet" : 0;
            }
            if (message.image_quality != null && message.hasOwnProperty("image_quality"))
                object.image_quality = options.enums === String ? $root.hbb.ImageQuality[message.image_quality] === undefined ? message.image_quality : $root.hbb.ImageQuality[message.image_quality] : message.image_quality;
            if (message.lock_after_session_end != null && message.hasOwnProperty("lock_after_session_end"))
                object.lock_after_session_end = options.enums === String ? $root.hbb.OptionMessage.BoolOption[message.lock_after_session_end] === undefined ? message.lock_after_session_end : $root.hbb.OptionMessage.BoolOption[message.lock_after_session_end] : message.lock_after_session_end;
            if (message.show_remote_cursor != null && message.hasOwnProperty("show_remote_cursor"))
                object.show_remote_cursor = options.enums === String ? $root.hbb.OptionMessage.BoolOption[message.show_remote_cursor] === undefined ? message.show_remote_cursor : $root.hbb.OptionMessage.BoolOption[message.show_remote_cursor] : message.show_remote_cursor;
            if (message.privacy_mode != null && message.hasOwnProperty("privacy_mode"))
                object.privacy_mode = options.enums === String ? $root.hbb.OptionMessage.BoolOption[message.privacy_mode] === undefined ? message.privacy_mode : $root.hbb.OptionMessage.BoolOption[message.privacy_mode] : message.privacy_mode;
            if (message.block_input != null && message.hasOwnProperty("block_input"))
                object.block_input = options.enums === String ? $root.hbb.OptionMessage.BoolOption[message.block_input] === undefined ? message.block_input : $root.hbb.OptionMessage.BoolOption[message.block_input] : message.block_input;
            if (message.custom_image_quality != null && message.hasOwnProperty("custom_image_quality"))
                object.custom_image_quality = message.custom_image_quality;
            if (message.disable_audio != null && message.hasOwnProperty("disable_audio"))
                object.disable_audio = options.enums === String ? $root.hbb.OptionMessage.BoolOption[message.disable_audio] === undefined ? message.disable_audio : $root.hbb.OptionMessage.BoolOption[message.disable_audio] : message.disable_audio;
            if (message.disable_clipboard != null && message.hasOwnProperty("disable_clipboard"))
                object.disable_clipboard = options.enums === String ? $root.hbb.OptionMessage.BoolOption[message.disable_clipboard] === undefined ? message.disable_clipboard : $root.hbb.OptionMessage.BoolOption[message.disable_clipboard] : message.disable_clipboard;
            if (message.enable_file_transfer != null && message.hasOwnProperty("enable_file_transfer"))
                object.enable_file_transfer = options.enums === String ? $root.hbb.OptionMessage.BoolOption[message.enable_file_transfer] === undefined ? message.enable_file_transfer : $root.hbb.OptionMessage.BoolOption[message.enable_file_transfer] : message.enable_file_transfer;
            if (message.supported_decoding != null && message.hasOwnProperty("supported_decoding"))
                object.supported_decoding = $root.hbb.SupportedDecoding.toObject(message.supported_decoding, options);
            if (message.custom_fps != null && message.hasOwnProperty("custom_fps"))
                object.custom_fps = message.custom_fps;
            if (message.disable_keyboard != null && message.hasOwnProperty("disable_keyboard"))
                object.disable_keyboard = options.enums === String ? $root.hbb.OptionMessage.BoolOption[message.disable_keyboard] === undefined ? message.disable_keyboard : $root.hbb.OptionMessage.BoolOption[message.disable_keyboard] : message.disable_keyboard;
            if (message.follow_remote_cursor != null && message.hasOwnProperty("follow_remote_cursor"))
                object.follow_remote_cursor = options.enums === String ? $root.hbb.OptionMessage.BoolOption[message.follow_remote_cursor] === undefined ? message.follow_remote_cursor : $root.hbb.OptionMessage.BoolOption[message.follow_remote_cursor] : message.follow_remote_cursor;
            if (message.follow_remote_window != null && message.hasOwnProperty("follow_remote_window"))
                object.follow_remote_window = options.enums === String ? $root.hbb.OptionMessage.BoolOption[message.follow_remote_window] === undefined ? message.follow_remote_window : $root.hbb.OptionMessage.BoolOption[message.follow_remote_window] : message.follow_remote_window;
            if (message.disable_camera != null && message.hasOwnProperty("disable_camera"))
                object.disable_camera = options.enums === String ? $root.hbb.OptionMessage.BoolOption[message.disable_camera] === undefined ? message.disable_camera : $root.hbb.OptionMessage.BoolOption[message.disable_camera] : message.disable_camera;
            return object;
        };

        /**
         * Converts this OptionMessage to JSON.
         * @function toJSON
         * @memberof hbb.OptionMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        OptionMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for OptionMessage
         * @function getTypeUrl
         * @memberof hbb.OptionMessage
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        OptionMessage.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.OptionMessage";
        };

        /**
         * BoolOption enum.
         * @name hbb.OptionMessage.BoolOption
         * @enum {number}
         * @property {number} NotSet=0 NotSet value
         * @property {number} No=1 No value
         * @property {number} Yes=2 Yes value
         */
        OptionMessage.BoolOption = (function() {
            const valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "NotSet"] = 0;
            values[valuesById[1] = "No"] = 1;
            values[valuesById[2] = "Yes"] = 2;
            return values;
        })();

        return OptionMessage;
    })();

    hbb.TestDelay = (function() {

        /**
         * Properties of a TestDelay.
         * @memberof hbb
         * @interface ITestDelay
         * @property {number|Long|null} [time] TestDelay time
         * @property {boolean|null} [from_client] TestDelay from_client
         * @property {number|null} [last_delay] TestDelay last_delay
         * @property {number|null} [target_bitrate] TestDelay target_bitrate
         */

        /**
         * Constructs a new TestDelay.
         * @memberof hbb
         * @classdesc Represents a TestDelay.
         * @implements ITestDelay
         * @constructor
         * @param {hbb.ITestDelay=} [properties] Properties to set
         */
        function TestDelay(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * TestDelay time.
         * @member {number|Long} time
         * @memberof hbb.TestDelay
         * @instance
         */
        TestDelay.prototype.time = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * TestDelay from_client.
         * @member {boolean} from_client
         * @memberof hbb.TestDelay
         * @instance
         */
        TestDelay.prototype.from_client = false;

        /**
         * TestDelay last_delay.
         * @member {number} last_delay
         * @memberof hbb.TestDelay
         * @instance
         */
        TestDelay.prototype.last_delay = 0;

        /**
         * TestDelay target_bitrate.
         * @member {number} target_bitrate
         * @memberof hbb.TestDelay
         * @instance
         */
        TestDelay.prototype.target_bitrate = 0;

        /**
         * Creates a new TestDelay instance using the specified properties.
         * @function create
         * @memberof hbb.TestDelay
         * @static
         * @param {hbb.ITestDelay=} [properties] Properties to set
         * @returns {hbb.TestDelay} TestDelay instance
         */
        TestDelay.create = function create(properties) {
            return new TestDelay(properties);
        };

        /**
         * Encodes the specified TestDelay message. Does not implicitly {@link hbb.TestDelay.verify|verify} messages.
         * @function encode
         * @memberof hbb.TestDelay
         * @static
         * @param {hbb.ITestDelay} message TestDelay message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        TestDelay.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.time != null && Object.hasOwnProperty.call(message, "time"))
                writer.uint32(/* id 1, wireType 0 =*/8).int64(message.time);
            if (message.from_client != null && Object.hasOwnProperty.call(message, "from_client"))
                writer.uint32(/* id 2, wireType 0 =*/16).bool(message.from_client);
            if (message.last_delay != null && Object.hasOwnProperty.call(message, "last_delay"))
                writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.last_delay);
            if (message.target_bitrate != null && Object.hasOwnProperty.call(message, "target_bitrate"))
                writer.uint32(/* id 4, wireType 0 =*/32).uint32(message.target_bitrate);
            return writer;
        };

        /**
         * Encodes the specified TestDelay message, length delimited. Does not implicitly {@link hbb.TestDelay.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.TestDelay
         * @static
         * @param {hbb.ITestDelay} message TestDelay message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        TestDelay.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a TestDelay message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.TestDelay
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.TestDelay} TestDelay
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        TestDelay.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.TestDelay();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.time = reader.int64();
                        break;
                    }
                case 2: {
                        message.from_client = reader.bool();
                        break;
                    }
                case 3: {
                        message.last_delay = reader.uint32();
                        break;
                    }
                case 4: {
                        message.target_bitrate = reader.uint32();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a TestDelay message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.TestDelay
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.TestDelay} TestDelay
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        TestDelay.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a TestDelay message.
         * @function verify
         * @memberof hbb.TestDelay
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        TestDelay.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.time != null && message.hasOwnProperty("time"))
                if (!$util.isInteger(message.time) && !(message.time && $util.isInteger(message.time.low) && $util.isInteger(message.time.high)))
                    return "time: integer|Long expected";
            if (message.from_client != null && message.hasOwnProperty("from_client"))
                if (typeof message.from_client !== "boolean")
                    return "from_client: boolean expected";
            if (message.last_delay != null && message.hasOwnProperty("last_delay"))
                if (!$util.isInteger(message.last_delay))
                    return "last_delay: integer expected";
            if (message.target_bitrate != null && message.hasOwnProperty("target_bitrate"))
                if (!$util.isInteger(message.target_bitrate))
                    return "target_bitrate: integer expected";
            return null;
        };

        /**
         * Creates a TestDelay message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.TestDelay
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.TestDelay} TestDelay
         */
        TestDelay.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.TestDelay)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.TestDelay();
            if (object.time != null)
                if ($util.Long)
                    (message.time = $util.Long.fromValue(object.time)).unsigned = false;
                else if (typeof object.time === "string")
                    message.time = parseInt(object.time, 10);
                else if (typeof object.time === "number")
                    message.time = object.time;
                else if (typeof object.time === "object")
                    message.time = new $util.LongBits(object.time.low >>> 0, object.time.high >>> 0).toNumber();
            if (object.from_client != null)
                message.from_client = Boolean(object.from_client);
            if (object.last_delay != null)
                message.last_delay = object.last_delay >>> 0;
            if (object.target_bitrate != null)
                message.target_bitrate = object.target_bitrate >>> 0;
            return message;
        };

        /**
         * Creates a plain object from a TestDelay message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.TestDelay
         * @static
         * @param {hbb.TestDelay} message TestDelay
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        TestDelay.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                if ($util.Long) {
                    let long = new $util.Long(0, 0, false);
                    object.time = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.time = options.longs === String ? "0" : 0;
                object.from_client = false;
                object.last_delay = 0;
                object.target_bitrate = 0;
            }
            if (message.time != null && message.hasOwnProperty("time"))
                if (typeof message.time === "number")
                    object.time = options.longs === String ? String(message.time) : message.time;
                else
                    object.time = options.longs === String ? $util.Long.prototype.toString.call(message.time) : options.longs === Number ? new $util.LongBits(message.time.low >>> 0, message.time.high >>> 0).toNumber() : message.time;
            if (message.from_client != null && message.hasOwnProperty("from_client"))
                object.from_client = message.from_client;
            if (message.last_delay != null && message.hasOwnProperty("last_delay"))
                object.last_delay = message.last_delay;
            if (message.target_bitrate != null && message.hasOwnProperty("target_bitrate"))
                object.target_bitrate = message.target_bitrate;
            return object;
        };

        /**
         * Converts this TestDelay to JSON.
         * @function toJSON
         * @memberof hbb.TestDelay
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        TestDelay.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for TestDelay
         * @function getTypeUrl
         * @memberof hbb.TestDelay
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        TestDelay.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.TestDelay";
        };

        return TestDelay;
    })();

    hbb.PublicKey = (function() {

        /**
         * Properties of a PublicKey.
         * @memberof hbb
         * @interface IPublicKey
         * @property {Uint8Array|null} [asymmetric_value] PublicKey asymmetric_value
         * @property {Uint8Array|null} [symmetric_value] PublicKey symmetric_value
         */

        /**
         * Constructs a new PublicKey.
         * @memberof hbb
         * @classdesc Represents a PublicKey.
         * @implements IPublicKey
         * @constructor
         * @param {hbb.IPublicKey=} [properties] Properties to set
         */
        function PublicKey(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * PublicKey asymmetric_value.
         * @member {Uint8Array} asymmetric_value
         * @memberof hbb.PublicKey
         * @instance
         */
        PublicKey.prototype.asymmetric_value = $util.newBuffer([]);

        /**
         * PublicKey symmetric_value.
         * @member {Uint8Array} symmetric_value
         * @memberof hbb.PublicKey
         * @instance
         */
        PublicKey.prototype.symmetric_value = $util.newBuffer([]);

        /**
         * Creates a new PublicKey instance using the specified properties.
         * @function create
         * @memberof hbb.PublicKey
         * @static
         * @param {hbb.IPublicKey=} [properties] Properties to set
         * @returns {hbb.PublicKey} PublicKey instance
         */
        PublicKey.create = function create(properties) {
            return new PublicKey(properties);
        };

        /**
         * Encodes the specified PublicKey message. Does not implicitly {@link hbb.PublicKey.verify|verify} messages.
         * @function encode
         * @memberof hbb.PublicKey
         * @static
         * @param {hbb.IPublicKey} message PublicKey message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        PublicKey.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.asymmetric_value != null && Object.hasOwnProperty.call(message, "asymmetric_value"))
                writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.asymmetric_value);
            if (message.symmetric_value != null && Object.hasOwnProperty.call(message, "symmetric_value"))
                writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.symmetric_value);
            return writer;
        };

        /**
         * Encodes the specified PublicKey message, length delimited. Does not implicitly {@link hbb.PublicKey.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.PublicKey
         * @static
         * @param {hbb.IPublicKey} message PublicKey message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        PublicKey.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a PublicKey message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.PublicKey
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.PublicKey} PublicKey
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        PublicKey.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.PublicKey();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.asymmetric_value = reader.bytes();
                        break;
                    }
                case 2: {
                        message.symmetric_value = reader.bytes();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a PublicKey message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.PublicKey
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.PublicKey} PublicKey
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        PublicKey.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a PublicKey message.
         * @function verify
         * @memberof hbb.PublicKey
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        PublicKey.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.asymmetric_value != null && message.hasOwnProperty("asymmetric_value"))
                if (!(message.asymmetric_value && typeof message.asymmetric_value.length === "number" || $util.isString(message.asymmetric_value)))
                    return "asymmetric_value: buffer expected";
            if (message.symmetric_value != null && message.hasOwnProperty("symmetric_value"))
                if (!(message.symmetric_value && typeof message.symmetric_value.length === "number" || $util.isString(message.symmetric_value)))
                    return "symmetric_value: buffer expected";
            return null;
        };

        /**
         * Creates a PublicKey message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.PublicKey
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.PublicKey} PublicKey
         */
        PublicKey.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.PublicKey)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.PublicKey();
            if (object.asymmetric_value != null)
                if (typeof object.asymmetric_value === "string")
                    $util.base64.decode(object.asymmetric_value, message.asymmetric_value = $util.newBuffer($util.base64.length(object.asymmetric_value)), 0);
                else if (object.asymmetric_value.length >= 0)
                    message.asymmetric_value = object.asymmetric_value;
            if (object.symmetric_value != null)
                if (typeof object.symmetric_value === "string")
                    $util.base64.decode(object.symmetric_value, message.symmetric_value = $util.newBuffer($util.base64.length(object.symmetric_value)), 0);
                else if (object.symmetric_value.length >= 0)
                    message.symmetric_value = object.symmetric_value;
            return message;
        };

        /**
         * Creates a plain object from a PublicKey message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.PublicKey
         * @static
         * @param {hbb.PublicKey} message PublicKey
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        PublicKey.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                if (options.bytes === String)
                    object.asymmetric_value = "";
                else {
                    object.asymmetric_value = [];
                    if (options.bytes !== Array)
                        object.asymmetric_value = $util.newBuffer(object.asymmetric_value);
                }
                if (options.bytes === String)
                    object.symmetric_value = "";
                else {
                    object.symmetric_value = [];
                    if (options.bytes !== Array)
                        object.symmetric_value = $util.newBuffer(object.symmetric_value);
                }
            }
            if (message.asymmetric_value != null && message.hasOwnProperty("asymmetric_value"))
                object.asymmetric_value = options.bytes === String ? $util.base64.encode(message.asymmetric_value, 0, message.asymmetric_value.length) : options.bytes === Array ? Array.prototype.slice.call(message.asymmetric_value) : message.asymmetric_value;
            if (message.symmetric_value != null && message.hasOwnProperty("symmetric_value"))
                object.symmetric_value = options.bytes === String ? $util.base64.encode(message.symmetric_value, 0, message.symmetric_value.length) : options.bytes === Array ? Array.prototype.slice.call(message.symmetric_value) : message.symmetric_value;
            return object;
        };

        /**
         * Converts this PublicKey to JSON.
         * @function toJSON
         * @memberof hbb.PublicKey
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        PublicKey.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for PublicKey
         * @function getTypeUrl
         * @memberof hbb.PublicKey
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        PublicKey.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.PublicKey";
        };

        return PublicKey;
    })();

    hbb.SignedId = (function() {

        /**
         * Properties of a SignedId.
         * @memberof hbb
         * @interface ISignedId
         * @property {Uint8Array|null} [id] SignedId id
         */

        /**
         * Constructs a new SignedId.
         * @memberof hbb
         * @classdesc Represents a SignedId.
         * @implements ISignedId
         * @constructor
         * @param {hbb.ISignedId=} [properties] Properties to set
         */
        function SignedId(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * SignedId id.
         * @member {Uint8Array} id
         * @memberof hbb.SignedId
         * @instance
         */
        SignedId.prototype.id = $util.newBuffer([]);

        /**
         * Creates a new SignedId instance using the specified properties.
         * @function create
         * @memberof hbb.SignedId
         * @static
         * @param {hbb.ISignedId=} [properties] Properties to set
         * @returns {hbb.SignedId} SignedId instance
         */
        SignedId.create = function create(properties) {
            return new SignedId(properties);
        };

        /**
         * Encodes the specified SignedId message. Does not implicitly {@link hbb.SignedId.verify|verify} messages.
         * @function encode
         * @memberof hbb.SignedId
         * @static
         * @param {hbb.ISignedId} message SignedId message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SignedId.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.id != null && Object.hasOwnProperty.call(message, "id"))
                writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.id);
            return writer;
        };

        /**
         * Encodes the specified SignedId message, length delimited. Does not implicitly {@link hbb.SignedId.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.SignedId
         * @static
         * @param {hbb.ISignedId} message SignedId message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SignedId.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a SignedId message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.SignedId
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.SignedId} SignedId
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SignedId.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.SignedId();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.id = reader.bytes();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a SignedId message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.SignedId
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.SignedId} SignedId
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SignedId.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a SignedId message.
         * @function verify
         * @memberof hbb.SignedId
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        SignedId.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.id != null && message.hasOwnProperty("id"))
                if (!(message.id && typeof message.id.length === "number" || $util.isString(message.id)))
                    return "id: buffer expected";
            return null;
        };

        /**
         * Creates a SignedId message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.SignedId
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.SignedId} SignedId
         */
        SignedId.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.SignedId)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.SignedId();
            if (object.id != null)
                if (typeof object.id === "string")
                    $util.base64.decode(object.id, message.id = $util.newBuffer($util.base64.length(object.id)), 0);
                else if (object.id.length >= 0)
                    message.id = object.id;
            return message;
        };

        /**
         * Creates a plain object from a SignedId message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.SignedId
         * @static
         * @param {hbb.SignedId} message SignedId
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        SignedId.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults)
                if (options.bytes === String)
                    object.id = "";
                else {
                    object.id = [];
                    if (options.bytes !== Array)
                        object.id = $util.newBuffer(object.id);
                }
            if (message.id != null && message.hasOwnProperty("id"))
                object.id = options.bytes === String ? $util.base64.encode(message.id, 0, message.id.length) : options.bytes === Array ? Array.prototype.slice.call(message.id) : message.id;
            return object;
        };

        /**
         * Converts this SignedId to JSON.
         * @function toJSON
         * @memberof hbb.SignedId
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        SignedId.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for SignedId
         * @function getTypeUrl
         * @memberof hbb.SignedId
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        SignedId.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.SignedId";
        };

        return SignedId;
    })();

    hbb.AudioFormat = (function() {

        /**
         * Properties of an AudioFormat.
         * @memberof hbb
         * @interface IAudioFormat
         * @property {number|null} [sample_rate] AudioFormat sample_rate
         * @property {number|null} [channels] AudioFormat channels
         */

        /**
         * Constructs a new AudioFormat.
         * @memberof hbb
         * @classdesc Represents an AudioFormat.
         * @implements IAudioFormat
         * @constructor
         * @param {hbb.IAudioFormat=} [properties] Properties to set
         */
        function AudioFormat(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * AudioFormat sample_rate.
         * @member {number} sample_rate
         * @memberof hbb.AudioFormat
         * @instance
         */
        AudioFormat.prototype.sample_rate = 0;

        /**
         * AudioFormat channels.
         * @member {number} channels
         * @memberof hbb.AudioFormat
         * @instance
         */
        AudioFormat.prototype.channels = 0;

        /**
         * Creates a new AudioFormat instance using the specified properties.
         * @function create
         * @memberof hbb.AudioFormat
         * @static
         * @param {hbb.IAudioFormat=} [properties] Properties to set
         * @returns {hbb.AudioFormat} AudioFormat instance
         */
        AudioFormat.create = function create(properties) {
            return new AudioFormat(properties);
        };

        /**
         * Encodes the specified AudioFormat message. Does not implicitly {@link hbb.AudioFormat.verify|verify} messages.
         * @function encode
         * @memberof hbb.AudioFormat
         * @static
         * @param {hbb.IAudioFormat} message AudioFormat message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        AudioFormat.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.sample_rate != null && Object.hasOwnProperty.call(message, "sample_rate"))
                writer.uint32(/* id 1, wireType 0 =*/8).uint32(message.sample_rate);
            if (message.channels != null && Object.hasOwnProperty.call(message, "channels"))
                writer.uint32(/* id 2, wireType 0 =*/16).uint32(message.channels);
            return writer;
        };

        /**
         * Encodes the specified AudioFormat message, length delimited. Does not implicitly {@link hbb.AudioFormat.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.AudioFormat
         * @static
         * @param {hbb.IAudioFormat} message AudioFormat message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        AudioFormat.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an AudioFormat message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.AudioFormat
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.AudioFormat} AudioFormat
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        AudioFormat.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.AudioFormat();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.sample_rate = reader.uint32();
                        break;
                    }
                case 2: {
                        message.channels = reader.uint32();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an AudioFormat message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.AudioFormat
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.AudioFormat} AudioFormat
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        AudioFormat.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an AudioFormat message.
         * @function verify
         * @memberof hbb.AudioFormat
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        AudioFormat.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.sample_rate != null && message.hasOwnProperty("sample_rate"))
                if (!$util.isInteger(message.sample_rate))
                    return "sample_rate: integer expected";
            if (message.channels != null && message.hasOwnProperty("channels"))
                if (!$util.isInteger(message.channels))
                    return "channels: integer expected";
            return null;
        };

        /**
         * Creates an AudioFormat message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.AudioFormat
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.AudioFormat} AudioFormat
         */
        AudioFormat.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.AudioFormat)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.AudioFormat();
            if (object.sample_rate != null)
                message.sample_rate = object.sample_rate >>> 0;
            if (object.channels != null)
                message.channels = object.channels >>> 0;
            return message;
        };

        /**
         * Creates a plain object from an AudioFormat message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.AudioFormat
         * @static
         * @param {hbb.AudioFormat} message AudioFormat
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        AudioFormat.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.sample_rate = 0;
                object.channels = 0;
            }
            if (message.sample_rate != null && message.hasOwnProperty("sample_rate"))
                object.sample_rate = message.sample_rate;
            if (message.channels != null && message.hasOwnProperty("channels"))
                object.channels = message.channels;
            return object;
        };

        /**
         * Converts this AudioFormat to JSON.
         * @function toJSON
         * @memberof hbb.AudioFormat
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        AudioFormat.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for AudioFormat
         * @function getTypeUrl
         * @memberof hbb.AudioFormat
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        AudioFormat.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.AudioFormat";
        };

        return AudioFormat;
    })();

    hbb.AudioFrame = (function() {

        /**
         * Properties of an AudioFrame.
         * @memberof hbb
         * @interface IAudioFrame
         * @property {Uint8Array|null} [data] AudioFrame data
         */

        /**
         * Constructs a new AudioFrame.
         * @memberof hbb
         * @classdesc Represents an AudioFrame.
         * @implements IAudioFrame
         * @constructor
         * @param {hbb.IAudioFrame=} [properties] Properties to set
         */
        function AudioFrame(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * AudioFrame data.
         * @member {Uint8Array} data
         * @memberof hbb.AudioFrame
         * @instance
         */
        AudioFrame.prototype.data = $util.newBuffer([]);

        /**
         * Creates a new AudioFrame instance using the specified properties.
         * @function create
         * @memberof hbb.AudioFrame
         * @static
         * @param {hbb.IAudioFrame=} [properties] Properties to set
         * @returns {hbb.AudioFrame} AudioFrame instance
         */
        AudioFrame.create = function create(properties) {
            return new AudioFrame(properties);
        };

        /**
         * Encodes the specified AudioFrame message. Does not implicitly {@link hbb.AudioFrame.verify|verify} messages.
         * @function encode
         * @memberof hbb.AudioFrame
         * @static
         * @param {hbb.IAudioFrame} message AudioFrame message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        AudioFrame.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.data != null && Object.hasOwnProperty.call(message, "data"))
                writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.data);
            return writer;
        };

        /**
         * Encodes the specified AudioFrame message, length delimited. Does not implicitly {@link hbb.AudioFrame.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.AudioFrame
         * @static
         * @param {hbb.IAudioFrame} message AudioFrame message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        AudioFrame.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an AudioFrame message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.AudioFrame
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.AudioFrame} AudioFrame
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        AudioFrame.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.AudioFrame();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.data = reader.bytes();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an AudioFrame message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.AudioFrame
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.AudioFrame} AudioFrame
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        AudioFrame.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an AudioFrame message.
         * @function verify
         * @memberof hbb.AudioFrame
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        AudioFrame.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.data != null && message.hasOwnProperty("data"))
                if (!(message.data && typeof message.data.length === "number" || $util.isString(message.data)))
                    return "data: buffer expected";
            return null;
        };

        /**
         * Creates an AudioFrame message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.AudioFrame
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.AudioFrame} AudioFrame
         */
        AudioFrame.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.AudioFrame)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.AudioFrame();
            if (object.data != null)
                if (typeof object.data === "string")
                    $util.base64.decode(object.data, message.data = $util.newBuffer($util.base64.length(object.data)), 0);
                else if (object.data.length >= 0)
                    message.data = object.data;
            return message;
        };

        /**
         * Creates a plain object from an AudioFrame message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.AudioFrame
         * @static
         * @param {hbb.AudioFrame} message AudioFrame
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        AudioFrame.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults)
                if (options.bytes === String)
                    object.data = "";
                else {
                    object.data = [];
                    if (options.bytes !== Array)
                        object.data = $util.newBuffer(object.data);
                }
            if (message.data != null && message.hasOwnProperty("data"))
                object.data = options.bytes === String ? $util.base64.encode(message.data, 0, message.data.length) : options.bytes === Array ? Array.prototype.slice.call(message.data) : message.data;
            return object;
        };

        /**
         * Converts this AudioFrame to JSON.
         * @function toJSON
         * @memberof hbb.AudioFrame
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        AudioFrame.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for AudioFrame
         * @function getTypeUrl
         * @memberof hbb.AudioFrame
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        AudioFrame.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.AudioFrame";
        };

        return AudioFrame;
    })();

    hbb.MessageBox = (function() {

        /**
         * Properties of a MessageBox.
         * @memberof hbb
         * @interface IMessageBox
         * @property {string|null} [msgtype] MessageBox msgtype
         * @property {string|null} [title] MessageBox title
         * @property {string|null} [text] MessageBox text
         * @property {string|null} [link] MessageBox link
         */

        /**
         * Constructs a new MessageBox.
         * @memberof hbb
         * @classdesc Represents a MessageBox.
         * @implements IMessageBox
         * @constructor
         * @param {hbb.IMessageBox=} [properties] Properties to set
         */
        function MessageBox(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * MessageBox msgtype.
         * @member {string} msgtype
         * @memberof hbb.MessageBox
         * @instance
         */
        MessageBox.prototype.msgtype = "";

        /**
         * MessageBox title.
         * @member {string} title
         * @memberof hbb.MessageBox
         * @instance
         */
        MessageBox.prototype.title = "";

        /**
         * MessageBox text.
         * @member {string} text
         * @memberof hbb.MessageBox
         * @instance
         */
        MessageBox.prototype.text = "";

        /**
         * MessageBox link.
         * @member {string} link
         * @memberof hbb.MessageBox
         * @instance
         */
        MessageBox.prototype.link = "";

        /**
         * Creates a new MessageBox instance using the specified properties.
         * @function create
         * @memberof hbb.MessageBox
         * @static
         * @param {hbb.IMessageBox=} [properties] Properties to set
         * @returns {hbb.MessageBox} MessageBox instance
         */
        MessageBox.create = function create(properties) {
            return new MessageBox(properties);
        };

        /**
         * Encodes the specified MessageBox message. Does not implicitly {@link hbb.MessageBox.verify|verify} messages.
         * @function encode
         * @memberof hbb.MessageBox
         * @static
         * @param {hbb.IMessageBox} message MessageBox message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        MessageBox.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.msgtype != null && Object.hasOwnProperty.call(message, "msgtype"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.msgtype);
            if (message.title != null && Object.hasOwnProperty.call(message, "title"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.title);
            if (message.text != null && Object.hasOwnProperty.call(message, "text"))
                writer.uint32(/* id 3, wireType 2 =*/26).string(message.text);
            if (message.link != null && Object.hasOwnProperty.call(message, "link"))
                writer.uint32(/* id 4, wireType 2 =*/34).string(message.link);
            return writer;
        };

        /**
         * Encodes the specified MessageBox message, length delimited. Does not implicitly {@link hbb.MessageBox.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.MessageBox
         * @static
         * @param {hbb.IMessageBox} message MessageBox message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        MessageBox.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a MessageBox message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.MessageBox
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.MessageBox} MessageBox
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        MessageBox.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.MessageBox();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.msgtype = reader.string();
                        break;
                    }
                case 2: {
                        message.title = reader.string();
                        break;
                    }
                case 3: {
                        message.text = reader.string();
                        break;
                    }
                case 4: {
                        message.link = reader.string();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a MessageBox message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.MessageBox
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.MessageBox} MessageBox
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        MessageBox.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a MessageBox message.
         * @function verify
         * @memberof hbb.MessageBox
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        MessageBox.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.msgtype != null && message.hasOwnProperty("msgtype"))
                if (!$util.isString(message.msgtype))
                    return "msgtype: string expected";
            if (message.title != null && message.hasOwnProperty("title"))
                if (!$util.isString(message.title))
                    return "title: string expected";
            if (message.text != null && message.hasOwnProperty("text"))
                if (!$util.isString(message.text))
                    return "text: string expected";
            if (message.link != null && message.hasOwnProperty("link"))
                if (!$util.isString(message.link))
                    return "link: string expected";
            return null;
        };

        /**
         * Creates a MessageBox message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.MessageBox
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.MessageBox} MessageBox
         */
        MessageBox.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.MessageBox)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.MessageBox();
            if (object.msgtype != null)
                message.msgtype = String(object.msgtype);
            if (object.title != null)
                message.title = String(object.title);
            if (object.text != null)
                message.text = String(object.text);
            if (object.link != null)
                message.link = String(object.link);
            return message;
        };

        /**
         * Creates a plain object from a MessageBox message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.MessageBox
         * @static
         * @param {hbb.MessageBox} message MessageBox
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        MessageBox.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.msgtype = "";
                object.title = "";
                object.text = "";
                object.link = "";
            }
            if (message.msgtype != null && message.hasOwnProperty("msgtype"))
                object.msgtype = message.msgtype;
            if (message.title != null && message.hasOwnProperty("title"))
                object.title = message.title;
            if (message.text != null && message.hasOwnProperty("text"))
                object.text = message.text;
            if (message.link != null && message.hasOwnProperty("link"))
                object.link = message.link;
            return object;
        };

        /**
         * Converts this MessageBox to JSON.
         * @function toJSON
         * @memberof hbb.MessageBox
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        MessageBox.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for MessageBox
         * @function getTypeUrl
         * @memberof hbb.MessageBox
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        MessageBox.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.MessageBox";
        };

        return MessageBox;
    })();

    hbb.BackNotification = (function() {

        /**
         * Properties of a BackNotification.
         * @memberof hbb
         * @interface IBackNotification
         * @property {hbb.BackNotification.PrivacyModeState|null} [privacy_mode_state] BackNotification privacy_mode_state
         * @property {hbb.BackNotification.BlockInputState|null} [block_input_state] BackNotification block_input_state
         * @property {string|null} [details] BackNotification details
         * @property {string|null} [impl_key] BackNotification impl_key
         */

        /**
         * Constructs a new BackNotification.
         * @memberof hbb
         * @classdesc Represents a BackNotification.
         * @implements IBackNotification
         * @constructor
         * @param {hbb.IBackNotification=} [properties] Properties to set
         */
        function BackNotification(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * BackNotification privacy_mode_state.
         * @member {hbb.BackNotification.PrivacyModeState|null|undefined} privacy_mode_state
         * @memberof hbb.BackNotification
         * @instance
         */
        BackNotification.prototype.privacy_mode_state = null;

        /**
         * BackNotification block_input_state.
         * @member {hbb.BackNotification.BlockInputState|null|undefined} block_input_state
         * @memberof hbb.BackNotification
         * @instance
         */
        BackNotification.prototype.block_input_state = null;

        /**
         * BackNotification details.
         * @member {string} details
         * @memberof hbb.BackNotification
         * @instance
         */
        BackNotification.prototype.details = "";

        /**
         * BackNotification impl_key.
         * @member {string} impl_key
         * @memberof hbb.BackNotification
         * @instance
         */
        BackNotification.prototype.impl_key = "";

        // OneOf field names bound to virtual getters and setters
        let $oneOfFields;

        /**
         * BackNotification union.
         * @member {"privacy_mode_state"|"block_input_state"|undefined} union
         * @memberof hbb.BackNotification
         * @instance
         */
        Object.defineProperty(BackNotification.prototype, "union", {
            get: $util.oneOfGetter($oneOfFields = ["privacy_mode_state", "block_input_state"]),
            set: $util.oneOfSetter($oneOfFields)
        });

        /**
         * Creates a new BackNotification instance using the specified properties.
         * @function create
         * @memberof hbb.BackNotification
         * @static
         * @param {hbb.IBackNotification=} [properties] Properties to set
         * @returns {hbb.BackNotification} BackNotification instance
         */
        BackNotification.create = function create(properties) {
            return new BackNotification(properties);
        };

        /**
         * Encodes the specified BackNotification message. Does not implicitly {@link hbb.BackNotification.verify|verify} messages.
         * @function encode
         * @memberof hbb.BackNotification
         * @static
         * @param {hbb.IBackNotification} message BackNotification message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        BackNotification.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.privacy_mode_state != null && Object.hasOwnProperty.call(message, "privacy_mode_state"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.privacy_mode_state);
            if (message.block_input_state != null && Object.hasOwnProperty.call(message, "block_input_state"))
                writer.uint32(/* id 2, wireType 0 =*/16).int32(message.block_input_state);
            if (message.details != null && Object.hasOwnProperty.call(message, "details"))
                writer.uint32(/* id 3, wireType 2 =*/26).string(message.details);
            if (message.impl_key != null && Object.hasOwnProperty.call(message, "impl_key"))
                writer.uint32(/* id 4, wireType 2 =*/34).string(message.impl_key);
            return writer;
        };

        /**
         * Encodes the specified BackNotification message, length delimited. Does not implicitly {@link hbb.BackNotification.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.BackNotification
         * @static
         * @param {hbb.IBackNotification} message BackNotification message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        BackNotification.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a BackNotification message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.BackNotification
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.BackNotification} BackNotification
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        BackNotification.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.BackNotification();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.privacy_mode_state = reader.int32();
                        break;
                    }
                case 2: {
                        message.block_input_state = reader.int32();
                        break;
                    }
                case 3: {
                        message.details = reader.string();
                        break;
                    }
                case 4: {
                        message.impl_key = reader.string();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a BackNotification message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.BackNotification
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.BackNotification} BackNotification
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        BackNotification.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a BackNotification message.
         * @function verify
         * @memberof hbb.BackNotification
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        BackNotification.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            let properties = {};
            if (message.privacy_mode_state != null && message.hasOwnProperty("privacy_mode_state")) {
                properties.union = 1;
                switch (message.privacy_mode_state) {
                default:
                    return "privacy_mode_state: enum value expected";
                case 0:
                case 2:
                case 3:
                case 4:
                case 5:
                case 6:
                case 7:
                case 8:
                case 9:
                case 10:
                case 11:
                    break;
                }
            }
            if (message.block_input_state != null && message.hasOwnProperty("block_input_state")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                switch (message.block_input_state) {
                default:
                    return "block_input_state: enum value expected";
                case 0:
                case 2:
                case 3:
                case 4:
                case 5:
                    break;
                }
            }
            if (message.details != null && message.hasOwnProperty("details"))
                if (!$util.isString(message.details))
                    return "details: string expected";
            if (message.impl_key != null && message.hasOwnProperty("impl_key"))
                if (!$util.isString(message.impl_key))
                    return "impl_key: string expected";
            return null;
        };

        /**
         * Creates a BackNotification message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.BackNotification
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.BackNotification} BackNotification
         */
        BackNotification.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.BackNotification)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.BackNotification();
            switch (object.privacy_mode_state) {
            default:
                if (typeof object.privacy_mode_state === "number") {
                    message.privacy_mode_state = object.privacy_mode_state;
                    break;
                }
                break;
            case "PrvStateUnknown":
            case 0:
                message.privacy_mode_state = 0;
                break;
            case "PrvOnByOther":
            case 2:
                message.privacy_mode_state = 2;
                break;
            case "PrvNotSupported":
            case 3:
                message.privacy_mode_state = 3;
                break;
            case "PrvOnSucceeded":
            case 4:
                message.privacy_mode_state = 4;
                break;
            case "PrvOnFailedDenied":
            case 5:
                message.privacy_mode_state = 5;
                break;
            case "PrvOnFailedPlugin":
            case 6:
                message.privacy_mode_state = 6;
                break;
            case "PrvOnFailed":
            case 7:
                message.privacy_mode_state = 7;
                break;
            case "PrvOffSucceeded":
            case 8:
                message.privacy_mode_state = 8;
                break;
            case "PrvOffByPeer":
            case 9:
                message.privacy_mode_state = 9;
                break;
            case "PrvOffFailed":
            case 10:
                message.privacy_mode_state = 10;
                break;
            case "PrvOffUnknown":
            case 11:
                message.privacy_mode_state = 11;
                break;
            }
            switch (object.block_input_state) {
            default:
                if (typeof object.block_input_state === "number") {
                    message.block_input_state = object.block_input_state;
                    break;
                }
                break;
            case "BlkStateUnknown":
            case 0:
                message.block_input_state = 0;
                break;
            case "BlkOnSucceeded":
            case 2:
                message.block_input_state = 2;
                break;
            case "BlkOnFailed":
            case 3:
                message.block_input_state = 3;
                break;
            case "BlkOffSucceeded":
            case 4:
                message.block_input_state = 4;
                break;
            case "BlkOffFailed":
            case 5:
                message.block_input_state = 5;
                break;
            }
            if (object.details != null)
                message.details = String(object.details);
            if (object.impl_key != null)
                message.impl_key = String(object.impl_key);
            return message;
        };

        /**
         * Creates a plain object from a BackNotification message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.BackNotification
         * @static
         * @param {hbb.BackNotification} message BackNotification
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        BackNotification.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.details = "";
                object.impl_key = "";
            }
            if (message.privacy_mode_state != null && message.hasOwnProperty("privacy_mode_state")) {
                object.privacy_mode_state = options.enums === String ? $root.hbb.BackNotification.PrivacyModeState[message.privacy_mode_state] === undefined ? message.privacy_mode_state : $root.hbb.BackNotification.PrivacyModeState[message.privacy_mode_state] : message.privacy_mode_state;
                if (options.oneofs)
                    object.union = "privacy_mode_state";
            }
            if (message.block_input_state != null && message.hasOwnProperty("block_input_state")) {
                object.block_input_state = options.enums === String ? $root.hbb.BackNotification.BlockInputState[message.block_input_state] === undefined ? message.block_input_state : $root.hbb.BackNotification.BlockInputState[message.block_input_state] : message.block_input_state;
                if (options.oneofs)
                    object.union = "block_input_state";
            }
            if (message.details != null && message.hasOwnProperty("details"))
                object.details = message.details;
            if (message.impl_key != null && message.hasOwnProperty("impl_key"))
                object.impl_key = message.impl_key;
            return object;
        };

        /**
         * Converts this BackNotification to JSON.
         * @function toJSON
         * @memberof hbb.BackNotification
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        BackNotification.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for BackNotification
         * @function getTypeUrl
         * @memberof hbb.BackNotification
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        BackNotification.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.BackNotification";
        };

        /**
         * BlockInputState enum.
         * @name hbb.BackNotification.BlockInputState
         * @enum {number}
         * @property {number} BlkStateUnknown=0 BlkStateUnknown value
         * @property {number} BlkOnSucceeded=2 BlkOnSucceeded value
         * @property {number} BlkOnFailed=3 BlkOnFailed value
         * @property {number} BlkOffSucceeded=4 BlkOffSucceeded value
         * @property {number} BlkOffFailed=5 BlkOffFailed value
         */
        BackNotification.BlockInputState = (function() {
            const valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "BlkStateUnknown"] = 0;
            values[valuesById[2] = "BlkOnSucceeded"] = 2;
            values[valuesById[3] = "BlkOnFailed"] = 3;
            values[valuesById[4] = "BlkOffSucceeded"] = 4;
            values[valuesById[5] = "BlkOffFailed"] = 5;
            return values;
        })();

        /**
         * PrivacyModeState enum.
         * @name hbb.BackNotification.PrivacyModeState
         * @enum {number}
         * @property {number} PrvStateUnknown=0 PrvStateUnknown value
         * @property {number} PrvOnByOther=2 PrvOnByOther value
         * @property {number} PrvNotSupported=3 PrvNotSupported value
         * @property {number} PrvOnSucceeded=4 PrvOnSucceeded value
         * @property {number} PrvOnFailedDenied=5 PrvOnFailedDenied value
         * @property {number} PrvOnFailedPlugin=6 PrvOnFailedPlugin value
         * @property {number} PrvOnFailed=7 PrvOnFailed value
         * @property {number} PrvOffSucceeded=8 PrvOffSucceeded value
         * @property {number} PrvOffByPeer=9 PrvOffByPeer value
         * @property {number} PrvOffFailed=10 PrvOffFailed value
         * @property {number} PrvOffUnknown=11 PrvOffUnknown value
         */
        BackNotification.PrivacyModeState = (function() {
            const valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "PrvStateUnknown"] = 0;
            values[valuesById[2] = "PrvOnByOther"] = 2;
            values[valuesById[3] = "PrvNotSupported"] = 3;
            values[valuesById[4] = "PrvOnSucceeded"] = 4;
            values[valuesById[5] = "PrvOnFailedDenied"] = 5;
            values[valuesById[6] = "PrvOnFailedPlugin"] = 6;
            values[valuesById[7] = "PrvOnFailed"] = 7;
            values[valuesById[8] = "PrvOffSucceeded"] = 8;
            values[valuesById[9] = "PrvOffByPeer"] = 9;
            values[valuesById[10] = "PrvOffFailed"] = 10;
            values[valuesById[11] = "PrvOffUnknown"] = 11;
            return values;
        })();

        return BackNotification;
    })();

    hbb.ElevationRequestWithLogon = (function() {

        /**
         * Properties of an ElevationRequestWithLogon.
         * @memberof hbb
         * @interface IElevationRequestWithLogon
         * @property {string|null} [username] ElevationRequestWithLogon username
         * @property {string|null} [password] ElevationRequestWithLogon password
         */

        /**
         * Constructs a new ElevationRequestWithLogon.
         * @memberof hbb
         * @classdesc Represents an ElevationRequestWithLogon.
         * @implements IElevationRequestWithLogon
         * @constructor
         * @param {hbb.IElevationRequestWithLogon=} [properties] Properties to set
         */
        function ElevationRequestWithLogon(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ElevationRequestWithLogon username.
         * @member {string} username
         * @memberof hbb.ElevationRequestWithLogon
         * @instance
         */
        ElevationRequestWithLogon.prototype.username = "";

        /**
         * ElevationRequestWithLogon password.
         * @member {string} password
         * @memberof hbb.ElevationRequestWithLogon
         * @instance
         */
        ElevationRequestWithLogon.prototype.password = "";

        /**
         * Creates a new ElevationRequestWithLogon instance using the specified properties.
         * @function create
         * @memberof hbb.ElevationRequestWithLogon
         * @static
         * @param {hbb.IElevationRequestWithLogon=} [properties] Properties to set
         * @returns {hbb.ElevationRequestWithLogon} ElevationRequestWithLogon instance
         */
        ElevationRequestWithLogon.create = function create(properties) {
            return new ElevationRequestWithLogon(properties);
        };

        /**
         * Encodes the specified ElevationRequestWithLogon message. Does not implicitly {@link hbb.ElevationRequestWithLogon.verify|verify} messages.
         * @function encode
         * @memberof hbb.ElevationRequestWithLogon
         * @static
         * @param {hbb.IElevationRequestWithLogon} message ElevationRequestWithLogon message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ElevationRequestWithLogon.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.username != null && Object.hasOwnProperty.call(message, "username"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.username);
            if (message.password != null && Object.hasOwnProperty.call(message, "password"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.password);
            return writer;
        };

        /**
         * Encodes the specified ElevationRequestWithLogon message, length delimited. Does not implicitly {@link hbb.ElevationRequestWithLogon.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.ElevationRequestWithLogon
         * @static
         * @param {hbb.IElevationRequestWithLogon} message ElevationRequestWithLogon message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ElevationRequestWithLogon.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an ElevationRequestWithLogon message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.ElevationRequestWithLogon
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.ElevationRequestWithLogon} ElevationRequestWithLogon
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ElevationRequestWithLogon.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.ElevationRequestWithLogon();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.username = reader.string();
                        break;
                    }
                case 2: {
                        message.password = reader.string();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an ElevationRequestWithLogon message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.ElevationRequestWithLogon
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.ElevationRequestWithLogon} ElevationRequestWithLogon
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ElevationRequestWithLogon.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an ElevationRequestWithLogon message.
         * @function verify
         * @memberof hbb.ElevationRequestWithLogon
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ElevationRequestWithLogon.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.username != null && message.hasOwnProperty("username"))
                if (!$util.isString(message.username))
                    return "username: string expected";
            if (message.password != null && message.hasOwnProperty("password"))
                if (!$util.isString(message.password))
                    return "password: string expected";
            return null;
        };

        /**
         * Creates an ElevationRequestWithLogon message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.ElevationRequestWithLogon
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.ElevationRequestWithLogon} ElevationRequestWithLogon
         */
        ElevationRequestWithLogon.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.ElevationRequestWithLogon)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.ElevationRequestWithLogon();
            if (object.username != null)
                message.username = String(object.username);
            if (object.password != null)
                message.password = String(object.password);
            return message;
        };

        /**
         * Creates a plain object from an ElevationRequestWithLogon message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.ElevationRequestWithLogon
         * @static
         * @param {hbb.ElevationRequestWithLogon} message ElevationRequestWithLogon
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ElevationRequestWithLogon.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.username = "";
                object.password = "";
            }
            if (message.username != null && message.hasOwnProperty("username"))
                object.username = message.username;
            if (message.password != null && message.hasOwnProperty("password"))
                object.password = message.password;
            return object;
        };

        /**
         * Converts this ElevationRequestWithLogon to JSON.
         * @function toJSON
         * @memberof hbb.ElevationRequestWithLogon
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ElevationRequestWithLogon.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for ElevationRequestWithLogon
         * @function getTypeUrl
         * @memberof hbb.ElevationRequestWithLogon
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        ElevationRequestWithLogon.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.ElevationRequestWithLogon";
        };

        return ElevationRequestWithLogon;
    })();

    hbb.ElevationRequest = (function() {

        /**
         * Properties of an ElevationRequest.
         * @memberof hbb
         * @interface IElevationRequest
         * @property {boolean|null} [direct] ElevationRequest direct
         * @property {hbb.IElevationRequestWithLogon|null} [logon] ElevationRequest logon
         */

        /**
         * Constructs a new ElevationRequest.
         * @memberof hbb
         * @classdesc Represents an ElevationRequest.
         * @implements IElevationRequest
         * @constructor
         * @param {hbb.IElevationRequest=} [properties] Properties to set
         */
        function ElevationRequest(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ElevationRequest direct.
         * @member {boolean|null|undefined} direct
         * @memberof hbb.ElevationRequest
         * @instance
         */
        ElevationRequest.prototype.direct = null;

        /**
         * ElevationRequest logon.
         * @member {hbb.IElevationRequestWithLogon|null|undefined} logon
         * @memberof hbb.ElevationRequest
         * @instance
         */
        ElevationRequest.prototype.logon = null;

        // OneOf field names bound to virtual getters and setters
        let $oneOfFields;

        /**
         * ElevationRequest union.
         * @member {"direct"|"logon"|undefined} union
         * @memberof hbb.ElevationRequest
         * @instance
         */
        Object.defineProperty(ElevationRequest.prototype, "union", {
            get: $util.oneOfGetter($oneOfFields = ["direct", "logon"]),
            set: $util.oneOfSetter($oneOfFields)
        });

        /**
         * Creates a new ElevationRequest instance using the specified properties.
         * @function create
         * @memberof hbb.ElevationRequest
         * @static
         * @param {hbb.IElevationRequest=} [properties] Properties to set
         * @returns {hbb.ElevationRequest} ElevationRequest instance
         */
        ElevationRequest.create = function create(properties) {
            return new ElevationRequest(properties);
        };

        /**
         * Encodes the specified ElevationRequest message. Does not implicitly {@link hbb.ElevationRequest.verify|verify} messages.
         * @function encode
         * @memberof hbb.ElevationRequest
         * @static
         * @param {hbb.IElevationRequest} message ElevationRequest message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ElevationRequest.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.direct != null && Object.hasOwnProperty.call(message, "direct"))
                writer.uint32(/* id 1, wireType 0 =*/8).bool(message.direct);
            if (message.logon != null && Object.hasOwnProperty.call(message, "logon"))
                $root.hbb.ElevationRequestWithLogon.encode(message.logon, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified ElevationRequest message, length delimited. Does not implicitly {@link hbb.ElevationRequest.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.ElevationRequest
         * @static
         * @param {hbb.IElevationRequest} message ElevationRequest message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ElevationRequest.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an ElevationRequest message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.ElevationRequest
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.ElevationRequest} ElevationRequest
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ElevationRequest.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.ElevationRequest();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.direct = reader.bool();
                        break;
                    }
                case 2: {
                        message.logon = $root.hbb.ElevationRequestWithLogon.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an ElevationRequest message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.ElevationRequest
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.ElevationRequest} ElevationRequest
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ElevationRequest.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an ElevationRequest message.
         * @function verify
         * @memberof hbb.ElevationRequest
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ElevationRequest.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            let properties = {};
            if (message.direct != null && message.hasOwnProperty("direct")) {
                properties.union = 1;
                if (typeof message.direct !== "boolean")
                    return "direct: boolean expected";
            }
            if (message.logon != null && message.hasOwnProperty("logon")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.ElevationRequestWithLogon.verify(message.logon, long + 1);
                    if (error)
                        return "logon." + error;
                }
            }
            return null;
        };

        /**
         * Creates an ElevationRequest message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.ElevationRequest
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.ElevationRequest} ElevationRequest
         */
        ElevationRequest.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.ElevationRequest)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.ElevationRequest();
            if (object.direct != null)
                message.direct = Boolean(object.direct);
            if (object.logon != null) {
                if (typeof object.logon !== "object")
                    throw TypeError(".hbb.ElevationRequest.logon: object expected");
                message.logon = $root.hbb.ElevationRequestWithLogon.fromObject(object.logon, long + 1);
            }
            return message;
        };

        /**
         * Creates a plain object from an ElevationRequest message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.ElevationRequest
         * @static
         * @param {hbb.ElevationRequest} message ElevationRequest
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ElevationRequest.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (message.direct != null && message.hasOwnProperty("direct")) {
                object.direct = message.direct;
                if (options.oneofs)
                    object.union = "direct";
            }
            if (message.logon != null && message.hasOwnProperty("logon")) {
                object.logon = $root.hbb.ElevationRequestWithLogon.toObject(message.logon, options);
                if (options.oneofs)
                    object.union = "logon";
            }
            return object;
        };

        /**
         * Converts this ElevationRequest to JSON.
         * @function toJSON
         * @memberof hbb.ElevationRequest
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ElevationRequest.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for ElevationRequest
         * @function getTypeUrl
         * @memberof hbb.ElevationRequest
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        ElevationRequest.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.ElevationRequest";
        };

        return ElevationRequest;
    })();

    hbb.SwitchSidesRequest = (function() {

        /**
         * Properties of a SwitchSidesRequest.
         * @memberof hbb
         * @interface ISwitchSidesRequest
         * @property {Uint8Array|null} [uuid] SwitchSidesRequest uuid
         */

        /**
         * Constructs a new SwitchSidesRequest.
         * @memberof hbb
         * @classdesc Represents a SwitchSidesRequest.
         * @implements ISwitchSidesRequest
         * @constructor
         * @param {hbb.ISwitchSidesRequest=} [properties] Properties to set
         */
        function SwitchSidesRequest(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * SwitchSidesRequest uuid.
         * @member {Uint8Array} uuid
         * @memberof hbb.SwitchSidesRequest
         * @instance
         */
        SwitchSidesRequest.prototype.uuid = $util.newBuffer([]);

        /**
         * Creates a new SwitchSidesRequest instance using the specified properties.
         * @function create
         * @memberof hbb.SwitchSidesRequest
         * @static
         * @param {hbb.ISwitchSidesRequest=} [properties] Properties to set
         * @returns {hbb.SwitchSidesRequest} SwitchSidesRequest instance
         */
        SwitchSidesRequest.create = function create(properties) {
            return new SwitchSidesRequest(properties);
        };

        /**
         * Encodes the specified SwitchSidesRequest message. Does not implicitly {@link hbb.SwitchSidesRequest.verify|verify} messages.
         * @function encode
         * @memberof hbb.SwitchSidesRequest
         * @static
         * @param {hbb.ISwitchSidesRequest} message SwitchSidesRequest message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SwitchSidesRequest.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.uuid != null && Object.hasOwnProperty.call(message, "uuid"))
                writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.uuid);
            return writer;
        };

        /**
         * Encodes the specified SwitchSidesRequest message, length delimited. Does not implicitly {@link hbb.SwitchSidesRequest.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.SwitchSidesRequest
         * @static
         * @param {hbb.ISwitchSidesRequest} message SwitchSidesRequest message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SwitchSidesRequest.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a SwitchSidesRequest message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.SwitchSidesRequest
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.SwitchSidesRequest} SwitchSidesRequest
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SwitchSidesRequest.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.SwitchSidesRequest();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.uuid = reader.bytes();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a SwitchSidesRequest message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.SwitchSidesRequest
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.SwitchSidesRequest} SwitchSidesRequest
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SwitchSidesRequest.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a SwitchSidesRequest message.
         * @function verify
         * @memberof hbb.SwitchSidesRequest
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        SwitchSidesRequest.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.uuid != null && message.hasOwnProperty("uuid"))
                if (!(message.uuid && typeof message.uuid.length === "number" || $util.isString(message.uuid)))
                    return "uuid: buffer expected";
            return null;
        };

        /**
         * Creates a SwitchSidesRequest message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.SwitchSidesRequest
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.SwitchSidesRequest} SwitchSidesRequest
         */
        SwitchSidesRequest.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.SwitchSidesRequest)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.SwitchSidesRequest();
            if (object.uuid != null)
                if (typeof object.uuid === "string")
                    $util.base64.decode(object.uuid, message.uuid = $util.newBuffer($util.base64.length(object.uuid)), 0);
                else if (object.uuid.length >= 0)
                    message.uuid = object.uuid;
            return message;
        };

        /**
         * Creates a plain object from a SwitchSidesRequest message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.SwitchSidesRequest
         * @static
         * @param {hbb.SwitchSidesRequest} message SwitchSidesRequest
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        SwitchSidesRequest.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults)
                if (options.bytes === String)
                    object.uuid = "";
                else {
                    object.uuid = [];
                    if (options.bytes !== Array)
                        object.uuid = $util.newBuffer(object.uuid);
                }
            if (message.uuid != null && message.hasOwnProperty("uuid"))
                object.uuid = options.bytes === String ? $util.base64.encode(message.uuid, 0, message.uuid.length) : options.bytes === Array ? Array.prototype.slice.call(message.uuid) : message.uuid;
            return object;
        };

        /**
         * Converts this SwitchSidesRequest to JSON.
         * @function toJSON
         * @memberof hbb.SwitchSidesRequest
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        SwitchSidesRequest.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for SwitchSidesRequest
         * @function getTypeUrl
         * @memberof hbb.SwitchSidesRequest
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        SwitchSidesRequest.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.SwitchSidesRequest";
        };

        return SwitchSidesRequest;
    })();

    hbb.SwitchSidesResponse = (function() {

        /**
         * Properties of a SwitchSidesResponse.
         * @memberof hbb
         * @interface ISwitchSidesResponse
         * @property {Uint8Array|null} [uuid] SwitchSidesResponse uuid
         * @property {hbb.ILoginRequest|null} [lr] SwitchSidesResponse lr
         */

        /**
         * Constructs a new SwitchSidesResponse.
         * @memberof hbb
         * @classdesc Represents a SwitchSidesResponse.
         * @implements ISwitchSidesResponse
         * @constructor
         * @param {hbb.ISwitchSidesResponse=} [properties] Properties to set
         */
        function SwitchSidesResponse(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * SwitchSidesResponse uuid.
         * @member {Uint8Array} uuid
         * @memberof hbb.SwitchSidesResponse
         * @instance
         */
        SwitchSidesResponse.prototype.uuid = $util.newBuffer([]);

        /**
         * SwitchSidesResponse lr.
         * @member {hbb.ILoginRequest|null|undefined} lr
         * @memberof hbb.SwitchSidesResponse
         * @instance
         */
        SwitchSidesResponse.prototype.lr = null;

        /**
         * Creates a new SwitchSidesResponse instance using the specified properties.
         * @function create
         * @memberof hbb.SwitchSidesResponse
         * @static
         * @param {hbb.ISwitchSidesResponse=} [properties] Properties to set
         * @returns {hbb.SwitchSidesResponse} SwitchSidesResponse instance
         */
        SwitchSidesResponse.create = function create(properties) {
            return new SwitchSidesResponse(properties);
        };

        /**
         * Encodes the specified SwitchSidesResponse message. Does not implicitly {@link hbb.SwitchSidesResponse.verify|verify} messages.
         * @function encode
         * @memberof hbb.SwitchSidesResponse
         * @static
         * @param {hbb.ISwitchSidesResponse} message SwitchSidesResponse message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SwitchSidesResponse.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.uuid != null && Object.hasOwnProperty.call(message, "uuid"))
                writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.uuid);
            if (message.lr != null && Object.hasOwnProperty.call(message, "lr"))
                $root.hbb.LoginRequest.encode(message.lr, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified SwitchSidesResponse message, length delimited. Does not implicitly {@link hbb.SwitchSidesResponse.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.SwitchSidesResponse
         * @static
         * @param {hbb.ISwitchSidesResponse} message SwitchSidesResponse message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SwitchSidesResponse.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a SwitchSidesResponse message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.SwitchSidesResponse
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.SwitchSidesResponse} SwitchSidesResponse
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SwitchSidesResponse.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.SwitchSidesResponse();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.uuid = reader.bytes();
                        break;
                    }
                case 2: {
                        message.lr = $root.hbb.LoginRequest.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a SwitchSidesResponse message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.SwitchSidesResponse
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.SwitchSidesResponse} SwitchSidesResponse
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SwitchSidesResponse.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a SwitchSidesResponse message.
         * @function verify
         * @memberof hbb.SwitchSidesResponse
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        SwitchSidesResponse.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.uuid != null && message.hasOwnProperty("uuid"))
                if (!(message.uuid && typeof message.uuid.length === "number" || $util.isString(message.uuid)))
                    return "uuid: buffer expected";
            if (message.lr != null && message.hasOwnProperty("lr")) {
                let error = $root.hbb.LoginRequest.verify(message.lr, long + 1);
                if (error)
                    return "lr." + error;
            }
            return null;
        };

        /**
         * Creates a SwitchSidesResponse message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.SwitchSidesResponse
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.SwitchSidesResponse} SwitchSidesResponse
         */
        SwitchSidesResponse.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.SwitchSidesResponse)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.SwitchSidesResponse();
            if (object.uuid != null)
                if (typeof object.uuid === "string")
                    $util.base64.decode(object.uuid, message.uuid = $util.newBuffer($util.base64.length(object.uuid)), 0);
                else if (object.uuid.length >= 0)
                    message.uuid = object.uuid;
            if (object.lr != null) {
                if (typeof object.lr !== "object")
                    throw TypeError(".hbb.SwitchSidesResponse.lr: object expected");
                message.lr = $root.hbb.LoginRequest.fromObject(object.lr, long + 1);
            }
            return message;
        };

        /**
         * Creates a plain object from a SwitchSidesResponse message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.SwitchSidesResponse
         * @static
         * @param {hbb.SwitchSidesResponse} message SwitchSidesResponse
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        SwitchSidesResponse.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                if (options.bytes === String)
                    object.uuid = "";
                else {
                    object.uuid = [];
                    if (options.bytes !== Array)
                        object.uuid = $util.newBuffer(object.uuid);
                }
                object.lr = null;
            }
            if (message.uuid != null && message.hasOwnProperty("uuid"))
                object.uuid = options.bytes === String ? $util.base64.encode(message.uuid, 0, message.uuid.length) : options.bytes === Array ? Array.prototype.slice.call(message.uuid) : message.uuid;
            if (message.lr != null && message.hasOwnProperty("lr"))
                object.lr = $root.hbb.LoginRequest.toObject(message.lr, options);
            return object;
        };

        /**
         * Converts this SwitchSidesResponse to JSON.
         * @function toJSON
         * @memberof hbb.SwitchSidesResponse
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        SwitchSidesResponse.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for SwitchSidesResponse
         * @function getTypeUrl
         * @memberof hbb.SwitchSidesResponse
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        SwitchSidesResponse.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.SwitchSidesResponse";
        };

        return SwitchSidesResponse;
    })();

    hbb.SwitchBack = (function() {

        /**
         * Properties of a SwitchBack.
         * @memberof hbb
         * @interface ISwitchBack
         */

        /**
         * Constructs a new SwitchBack.
         * @memberof hbb
         * @classdesc Represents a SwitchBack.
         * @implements ISwitchBack
         * @constructor
         * @param {hbb.ISwitchBack=} [properties] Properties to set
         */
        function SwitchBack(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * Creates a new SwitchBack instance using the specified properties.
         * @function create
         * @memberof hbb.SwitchBack
         * @static
         * @param {hbb.ISwitchBack=} [properties] Properties to set
         * @returns {hbb.SwitchBack} SwitchBack instance
         */
        SwitchBack.create = function create(properties) {
            return new SwitchBack(properties);
        };

        /**
         * Encodes the specified SwitchBack message. Does not implicitly {@link hbb.SwitchBack.verify|verify} messages.
         * @function encode
         * @memberof hbb.SwitchBack
         * @static
         * @param {hbb.ISwitchBack} message SwitchBack message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SwitchBack.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            return writer;
        };

        /**
         * Encodes the specified SwitchBack message, length delimited. Does not implicitly {@link hbb.SwitchBack.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.SwitchBack
         * @static
         * @param {hbb.ISwitchBack} message SwitchBack message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SwitchBack.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a SwitchBack message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.SwitchBack
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.SwitchBack} SwitchBack
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SwitchBack.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.SwitchBack();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a SwitchBack message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.SwitchBack
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.SwitchBack} SwitchBack
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SwitchBack.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a SwitchBack message.
         * @function verify
         * @memberof hbb.SwitchBack
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        SwitchBack.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            return null;
        };

        /**
         * Creates a SwitchBack message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.SwitchBack
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.SwitchBack} SwitchBack
         */
        SwitchBack.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.SwitchBack)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            return new $root.hbb.SwitchBack();
        };

        /**
         * Creates a plain object from a SwitchBack message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.SwitchBack
         * @static
         * @param {hbb.SwitchBack} message SwitchBack
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        SwitchBack.toObject = function toObject() {
            return {};
        };

        /**
         * Converts this SwitchBack to JSON.
         * @function toJSON
         * @memberof hbb.SwitchBack
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        SwitchBack.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for SwitchBack
         * @function getTypeUrl
         * @memberof hbb.SwitchBack
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        SwitchBack.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.SwitchBack";
        };

        return SwitchBack;
    })();

    hbb.PluginRequest = (function() {

        /**
         * Properties of a PluginRequest.
         * @memberof hbb
         * @interface IPluginRequest
         * @property {string|null} [id] PluginRequest id
         * @property {Uint8Array|null} [content] PluginRequest content
         */

        /**
         * Constructs a new PluginRequest.
         * @memberof hbb
         * @classdesc Represents a PluginRequest.
         * @implements IPluginRequest
         * @constructor
         * @param {hbb.IPluginRequest=} [properties] Properties to set
         */
        function PluginRequest(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * PluginRequest id.
         * @member {string} id
         * @memberof hbb.PluginRequest
         * @instance
         */
        PluginRequest.prototype.id = "";

        /**
         * PluginRequest content.
         * @member {Uint8Array} content
         * @memberof hbb.PluginRequest
         * @instance
         */
        PluginRequest.prototype.content = $util.newBuffer([]);

        /**
         * Creates a new PluginRequest instance using the specified properties.
         * @function create
         * @memberof hbb.PluginRequest
         * @static
         * @param {hbb.IPluginRequest=} [properties] Properties to set
         * @returns {hbb.PluginRequest} PluginRequest instance
         */
        PluginRequest.create = function create(properties) {
            return new PluginRequest(properties);
        };

        /**
         * Encodes the specified PluginRequest message. Does not implicitly {@link hbb.PluginRequest.verify|verify} messages.
         * @function encode
         * @memberof hbb.PluginRequest
         * @static
         * @param {hbb.IPluginRequest} message PluginRequest message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        PluginRequest.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.id != null && Object.hasOwnProperty.call(message, "id"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.id);
            if (message.content != null && Object.hasOwnProperty.call(message, "content"))
                writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.content);
            return writer;
        };

        /**
         * Encodes the specified PluginRequest message, length delimited. Does not implicitly {@link hbb.PluginRequest.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.PluginRequest
         * @static
         * @param {hbb.IPluginRequest} message PluginRequest message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        PluginRequest.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a PluginRequest message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.PluginRequest
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.PluginRequest} PluginRequest
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        PluginRequest.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.PluginRequest();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.id = reader.string();
                        break;
                    }
                case 2: {
                        message.content = reader.bytes();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a PluginRequest message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.PluginRequest
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.PluginRequest} PluginRequest
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        PluginRequest.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a PluginRequest message.
         * @function verify
         * @memberof hbb.PluginRequest
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        PluginRequest.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.id != null && message.hasOwnProperty("id"))
                if (!$util.isString(message.id))
                    return "id: string expected";
            if (message.content != null && message.hasOwnProperty("content"))
                if (!(message.content && typeof message.content.length === "number" || $util.isString(message.content)))
                    return "content: buffer expected";
            return null;
        };

        /**
         * Creates a PluginRequest message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.PluginRequest
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.PluginRequest} PluginRequest
         */
        PluginRequest.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.PluginRequest)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.PluginRequest();
            if (object.id != null)
                message.id = String(object.id);
            if (object.content != null)
                if (typeof object.content === "string")
                    $util.base64.decode(object.content, message.content = $util.newBuffer($util.base64.length(object.content)), 0);
                else if (object.content.length >= 0)
                    message.content = object.content;
            return message;
        };

        /**
         * Creates a plain object from a PluginRequest message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.PluginRequest
         * @static
         * @param {hbb.PluginRequest} message PluginRequest
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        PluginRequest.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.id = "";
                if (options.bytes === String)
                    object.content = "";
                else {
                    object.content = [];
                    if (options.bytes !== Array)
                        object.content = $util.newBuffer(object.content);
                }
            }
            if (message.id != null && message.hasOwnProperty("id"))
                object.id = message.id;
            if (message.content != null && message.hasOwnProperty("content"))
                object.content = options.bytes === String ? $util.base64.encode(message.content, 0, message.content.length) : options.bytes === Array ? Array.prototype.slice.call(message.content) : message.content;
            return object;
        };

        /**
         * Converts this PluginRequest to JSON.
         * @function toJSON
         * @memberof hbb.PluginRequest
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        PluginRequest.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for PluginRequest
         * @function getTypeUrl
         * @memberof hbb.PluginRequest
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        PluginRequest.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.PluginRequest";
        };

        return PluginRequest;
    })();

    hbb.PluginFailure = (function() {

        /**
         * Properties of a PluginFailure.
         * @memberof hbb
         * @interface IPluginFailure
         * @property {string|null} [id] PluginFailure id
         * @property {string|null} [name] PluginFailure name
         * @property {string|null} [msg] PluginFailure msg
         */

        /**
         * Constructs a new PluginFailure.
         * @memberof hbb
         * @classdesc Represents a PluginFailure.
         * @implements IPluginFailure
         * @constructor
         * @param {hbb.IPluginFailure=} [properties] Properties to set
         */
        function PluginFailure(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * PluginFailure id.
         * @member {string} id
         * @memberof hbb.PluginFailure
         * @instance
         */
        PluginFailure.prototype.id = "";

        /**
         * PluginFailure name.
         * @member {string} name
         * @memberof hbb.PluginFailure
         * @instance
         */
        PluginFailure.prototype.name = "";

        /**
         * PluginFailure msg.
         * @member {string} msg
         * @memberof hbb.PluginFailure
         * @instance
         */
        PluginFailure.prototype.msg = "";

        /**
         * Creates a new PluginFailure instance using the specified properties.
         * @function create
         * @memberof hbb.PluginFailure
         * @static
         * @param {hbb.IPluginFailure=} [properties] Properties to set
         * @returns {hbb.PluginFailure} PluginFailure instance
         */
        PluginFailure.create = function create(properties) {
            return new PluginFailure(properties);
        };

        /**
         * Encodes the specified PluginFailure message. Does not implicitly {@link hbb.PluginFailure.verify|verify} messages.
         * @function encode
         * @memberof hbb.PluginFailure
         * @static
         * @param {hbb.IPluginFailure} message PluginFailure message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        PluginFailure.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.id != null && Object.hasOwnProperty.call(message, "id"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.id);
            if (message.name != null && Object.hasOwnProperty.call(message, "name"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.name);
            if (message.msg != null && Object.hasOwnProperty.call(message, "msg"))
                writer.uint32(/* id 3, wireType 2 =*/26).string(message.msg);
            return writer;
        };

        /**
         * Encodes the specified PluginFailure message, length delimited. Does not implicitly {@link hbb.PluginFailure.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.PluginFailure
         * @static
         * @param {hbb.IPluginFailure} message PluginFailure message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        PluginFailure.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a PluginFailure message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.PluginFailure
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.PluginFailure} PluginFailure
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        PluginFailure.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.PluginFailure();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.id = reader.string();
                        break;
                    }
                case 2: {
                        message.name = reader.string();
                        break;
                    }
                case 3: {
                        message.msg = reader.string();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a PluginFailure message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.PluginFailure
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.PluginFailure} PluginFailure
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        PluginFailure.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a PluginFailure message.
         * @function verify
         * @memberof hbb.PluginFailure
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        PluginFailure.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.id != null && message.hasOwnProperty("id"))
                if (!$util.isString(message.id))
                    return "id: string expected";
            if (message.name != null && message.hasOwnProperty("name"))
                if (!$util.isString(message.name))
                    return "name: string expected";
            if (message.msg != null && message.hasOwnProperty("msg"))
                if (!$util.isString(message.msg))
                    return "msg: string expected";
            return null;
        };

        /**
         * Creates a PluginFailure message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.PluginFailure
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.PluginFailure} PluginFailure
         */
        PluginFailure.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.PluginFailure)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.PluginFailure();
            if (object.id != null)
                message.id = String(object.id);
            if (object.name != null)
                message.name = String(object.name);
            if (object.msg != null)
                message.msg = String(object.msg);
            return message;
        };

        /**
         * Creates a plain object from a PluginFailure message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.PluginFailure
         * @static
         * @param {hbb.PluginFailure} message PluginFailure
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        PluginFailure.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.id = "";
                object.name = "";
                object.msg = "";
            }
            if (message.id != null && message.hasOwnProperty("id"))
                object.id = message.id;
            if (message.name != null && message.hasOwnProperty("name"))
                object.name = message.name;
            if (message.msg != null && message.hasOwnProperty("msg"))
                object.msg = message.msg;
            return object;
        };

        /**
         * Converts this PluginFailure to JSON.
         * @function toJSON
         * @memberof hbb.PluginFailure
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        PluginFailure.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for PluginFailure
         * @function getTypeUrl
         * @memberof hbb.PluginFailure
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        PluginFailure.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.PluginFailure";
        };

        return PluginFailure;
    })();

    hbb.WindowsSessions = (function() {

        /**
         * Properties of a WindowsSessions.
         * @memberof hbb
         * @interface IWindowsSessions
         * @property {Array.<hbb.IWindowsSession>|null} [sessions] WindowsSessions sessions
         * @property {number|null} [current_sid] WindowsSessions current_sid
         */

        /**
         * Constructs a new WindowsSessions.
         * @memberof hbb
         * @classdesc Represents a WindowsSessions.
         * @implements IWindowsSessions
         * @constructor
         * @param {hbb.IWindowsSessions=} [properties] Properties to set
         */
        function WindowsSessions(properties) {
            this.sessions = [];
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * WindowsSessions sessions.
         * @member {Array.<hbb.IWindowsSession>} sessions
         * @memberof hbb.WindowsSessions
         * @instance
         */
        WindowsSessions.prototype.sessions = $util.emptyArray;

        /**
         * WindowsSessions current_sid.
         * @member {number} current_sid
         * @memberof hbb.WindowsSessions
         * @instance
         */
        WindowsSessions.prototype.current_sid = 0;

        /**
         * Creates a new WindowsSessions instance using the specified properties.
         * @function create
         * @memberof hbb.WindowsSessions
         * @static
         * @param {hbb.IWindowsSessions=} [properties] Properties to set
         * @returns {hbb.WindowsSessions} WindowsSessions instance
         */
        WindowsSessions.create = function create(properties) {
            return new WindowsSessions(properties);
        };

        /**
         * Encodes the specified WindowsSessions message. Does not implicitly {@link hbb.WindowsSessions.verify|verify} messages.
         * @function encode
         * @memberof hbb.WindowsSessions
         * @static
         * @param {hbb.IWindowsSessions} message WindowsSessions message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        WindowsSessions.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.sessions != null && message.sessions.length)
                for (let i = 0; i < message.sessions.length; ++i)
                    $root.hbb.WindowsSession.encode(message.sessions[i], writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.current_sid != null && Object.hasOwnProperty.call(message, "current_sid"))
                writer.uint32(/* id 2, wireType 0 =*/16).uint32(message.current_sid);
            return writer;
        };

        /**
         * Encodes the specified WindowsSessions message, length delimited. Does not implicitly {@link hbb.WindowsSessions.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.WindowsSessions
         * @static
         * @param {hbb.IWindowsSessions} message WindowsSessions message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        WindowsSessions.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a WindowsSessions message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.WindowsSessions
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.WindowsSessions} WindowsSessions
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        WindowsSessions.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.WindowsSessions();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        if (!(message.sessions && message.sessions.length))
                            message.sessions = [];
                        message.sessions.push($root.hbb.WindowsSession.decode(reader, reader.uint32(), undefined, long + 1));
                        break;
                    }
                case 2: {
                        message.current_sid = reader.uint32();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a WindowsSessions message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.WindowsSessions
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.WindowsSessions} WindowsSessions
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        WindowsSessions.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a WindowsSessions message.
         * @function verify
         * @memberof hbb.WindowsSessions
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        WindowsSessions.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.sessions != null && message.hasOwnProperty("sessions")) {
                if (!Array.isArray(message.sessions))
                    return "sessions: array expected";
                for (let i = 0; i < message.sessions.length; ++i) {
                    let error = $root.hbb.WindowsSession.verify(message.sessions[i], long + 1);
                    if (error)
                        return "sessions." + error;
                }
            }
            if (message.current_sid != null && message.hasOwnProperty("current_sid"))
                if (!$util.isInteger(message.current_sid))
                    return "current_sid: integer expected";
            return null;
        };

        /**
         * Creates a WindowsSessions message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.WindowsSessions
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.WindowsSessions} WindowsSessions
         */
        WindowsSessions.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.WindowsSessions)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.WindowsSessions();
            if (object.sessions) {
                if (!Array.isArray(object.sessions))
                    throw TypeError(".hbb.WindowsSessions.sessions: array expected");
                message.sessions = [];
                for (let i = 0; i < object.sessions.length; ++i) {
                    if (typeof object.sessions[i] !== "object")
                        throw TypeError(".hbb.WindowsSessions.sessions: object expected");
                    message.sessions[i] = $root.hbb.WindowsSession.fromObject(object.sessions[i], long + 1);
                }
            }
            if (object.current_sid != null)
                message.current_sid = object.current_sid >>> 0;
            return message;
        };

        /**
         * Creates a plain object from a WindowsSessions message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.WindowsSessions
         * @static
         * @param {hbb.WindowsSessions} message WindowsSessions
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        WindowsSessions.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.arrays || options.defaults)
                object.sessions = [];
            if (options.defaults)
                object.current_sid = 0;
            if (message.sessions && message.sessions.length) {
                object.sessions = [];
                for (let j = 0; j < message.sessions.length; ++j)
                    object.sessions[j] = $root.hbb.WindowsSession.toObject(message.sessions[j], options);
            }
            if (message.current_sid != null && message.hasOwnProperty("current_sid"))
                object.current_sid = message.current_sid;
            return object;
        };

        /**
         * Converts this WindowsSessions to JSON.
         * @function toJSON
         * @memberof hbb.WindowsSessions
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        WindowsSessions.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for WindowsSessions
         * @function getTypeUrl
         * @memberof hbb.WindowsSessions
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        WindowsSessions.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.WindowsSessions";
        };

        return WindowsSessions;
    })();

    hbb.MessageQuery = (function() {

        /**
         * Properties of a MessageQuery.
         * @memberof hbb
         * @interface IMessageQuery
         * @property {number|null} [switch_display] MessageQuery switch_display
         */

        /**
         * Constructs a new MessageQuery.
         * @memberof hbb
         * @classdesc Represents a MessageQuery.
         * @implements IMessageQuery
         * @constructor
         * @param {hbb.IMessageQuery=} [properties] Properties to set
         */
        function MessageQuery(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * MessageQuery switch_display.
         * @member {number} switch_display
         * @memberof hbb.MessageQuery
         * @instance
         */
        MessageQuery.prototype.switch_display = 0;

        /**
         * Creates a new MessageQuery instance using the specified properties.
         * @function create
         * @memberof hbb.MessageQuery
         * @static
         * @param {hbb.IMessageQuery=} [properties] Properties to set
         * @returns {hbb.MessageQuery} MessageQuery instance
         */
        MessageQuery.create = function create(properties) {
            return new MessageQuery(properties);
        };

        /**
         * Encodes the specified MessageQuery message. Does not implicitly {@link hbb.MessageQuery.verify|verify} messages.
         * @function encode
         * @memberof hbb.MessageQuery
         * @static
         * @param {hbb.IMessageQuery} message MessageQuery message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        MessageQuery.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.switch_display != null && Object.hasOwnProperty.call(message, "switch_display"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.switch_display);
            return writer;
        };

        /**
         * Encodes the specified MessageQuery message, length delimited. Does not implicitly {@link hbb.MessageQuery.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.MessageQuery
         * @static
         * @param {hbb.IMessageQuery} message MessageQuery message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        MessageQuery.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a MessageQuery message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.MessageQuery
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.MessageQuery} MessageQuery
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        MessageQuery.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.MessageQuery();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.switch_display = reader.int32();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a MessageQuery message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.MessageQuery
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.MessageQuery} MessageQuery
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        MessageQuery.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a MessageQuery message.
         * @function verify
         * @memberof hbb.MessageQuery
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        MessageQuery.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.switch_display != null && message.hasOwnProperty("switch_display"))
                if (!$util.isInteger(message.switch_display))
                    return "switch_display: integer expected";
            return null;
        };

        /**
         * Creates a MessageQuery message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.MessageQuery
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.MessageQuery} MessageQuery
         */
        MessageQuery.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.MessageQuery)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.MessageQuery();
            if (object.switch_display != null)
                message.switch_display = object.switch_display | 0;
            return message;
        };

        /**
         * Creates a plain object from a MessageQuery message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.MessageQuery
         * @static
         * @param {hbb.MessageQuery} message MessageQuery
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        MessageQuery.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults)
                object.switch_display = 0;
            if (message.switch_display != null && message.hasOwnProperty("switch_display"))
                object.switch_display = message.switch_display;
            return object;
        };

        /**
         * Converts this MessageQuery to JSON.
         * @function toJSON
         * @memberof hbb.MessageQuery
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        MessageQuery.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for MessageQuery
         * @function getTypeUrl
         * @memberof hbb.MessageQuery
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        MessageQuery.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.MessageQuery";
        };

        return MessageQuery;
    })();

    hbb.Misc = (function() {

        /**
         * Properties of a Misc.
         * @memberof hbb
         * @interface IMisc
         * @property {hbb.IChatMessage|null} [chat_message] Misc chat_message
         * @property {hbb.ISwitchDisplay|null} [switch_display] Misc switch_display
         * @property {hbb.IPermissionInfo|null} [permission_info] Misc permission_info
         * @property {hbb.IOptionMessage|null} [option] Misc option
         * @property {hbb.IAudioFormat|null} [audio_format] Misc audio_format
         * @property {string|null} [close_reason] Misc close_reason
         * @property {boolean|null} [refresh_video] Misc refresh_video
         * @property {boolean|null} [video_received] Misc video_received
         * @property {hbb.IBackNotification|null} [back_notification] Misc back_notification
         * @property {boolean|null} [restart_remote_device] Misc restart_remote_device
         * @property {boolean|null} [uac] Misc uac
         * @property {boolean|null} [foreground_window_elevated] Misc foreground_window_elevated
         * @property {boolean|null} [stop_service] Misc stop_service
         * @property {hbb.IElevationRequest|null} [elevation_request] Misc elevation_request
         * @property {string|null} [elevation_response] Misc elevation_response
         * @property {boolean|null} [portable_service_running] Misc portable_service_running
         * @property {hbb.ISwitchSidesRequest|null} [switch_sides_request] Misc switch_sides_request
         * @property {hbb.ISwitchBack|null} [switch_back] Misc switch_back
         * @property {hbb.IResolution|null} [change_resolution] Misc change_resolution
         * @property {hbb.IPluginRequest|null} [plugin_request] Misc plugin_request
         * @property {hbb.IPluginFailure|null} [plugin_failure] Misc plugin_failure
         * @property {number|null} [full_speed_fps] Misc full_speed_fps
         * @property {number|null} [auto_adjust_fps] Misc auto_adjust_fps
         * @property {boolean|null} [client_record_status] Misc client_record_status
         * @property {hbb.ICaptureDisplays|null} [capture_displays] Misc capture_displays
         * @property {number|null} [refresh_video_display] Misc refresh_video_display
         * @property {hbb.IToggleVirtualDisplay|null} [toggle_virtual_display] Misc toggle_virtual_display
         * @property {hbb.ITogglePrivacyMode|null} [toggle_privacy_mode] Misc toggle_privacy_mode
         * @property {hbb.ISupportedEncoding|null} [supported_encoding] Misc supported_encoding
         * @property {number|null} [selected_sid] Misc selected_sid
         * @property {hbb.IDisplayResolution|null} [change_display_resolution] Misc change_display_resolution
         * @property {hbb.IMessageQuery|null} [message_query] Misc message_query
         * @property {number|null} [follow_current_display] Misc follow_current_display
         */

        /**
         * Constructs a new Misc.
         * @memberof hbb
         * @classdesc Represents a Misc.
         * @implements IMisc
         * @constructor
         * @param {hbb.IMisc=} [properties] Properties to set
         */
        function Misc(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * Misc chat_message.
         * @member {hbb.IChatMessage|null|undefined} chat_message
         * @memberof hbb.Misc
         * @instance
         */
        Misc.prototype.chat_message = null;

        /**
         * Misc switch_display.
         * @member {hbb.ISwitchDisplay|null|undefined} switch_display
         * @memberof hbb.Misc
         * @instance
         */
        Misc.prototype.switch_display = null;

        /**
         * Misc permission_info.
         * @member {hbb.IPermissionInfo|null|undefined} permission_info
         * @memberof hbb.Misc
         * @instance
         */
        Misc.prototype.permission_info = null;

        /**
         * Misc option.
         * @member {hbb.IOptionMessage|null|undefined} option
         * @memberof hbb.Misc
         * @instance
         */
        Misc.prototype.option = null;

        /**
         * Misc audio_format.
         * @member {hbb.IAudioFormat|null|undefined} audio_format
         * @memberof hbb.Misc
         * @instance
         */
        Misc.prototype.audio_format = null;

        /**
         * Misc close_reason.
         * @member {string|null|undefined} close_reason
         * @memberof hbb.Misc
         * @instance
         */
        Misc.prototype.close_reason = null;

        /**
         * Misc refresh_video.
         * @member {boolean|null|undefined} refresh_video
         * @memberof hbb.Misc
         * @instance
         */
        Misc.prototype.refresh_video = null;

        /**
         * Misc video_received.
         * @member {boolean|null|undefined} video_received
         * @memberof hbb.Misc
         * @instance
         */
        Misc.prototype.video_received = null;

        /**
         * Misc back_notification.
         * @member {hbb.IBackNotification|null|undefined} back_notification
         * @memberof hbb.Misc
         * @instance
         */
        Misc.prototype.back_notification = null;

        /**
         * Misc restart_remote_device.
         * @member {boolean|null|undefined} restart_remote_device
         * @memberof hbb.Misc
         * @instance
         */
        Misc.prototype.restart_remote_device = null;

        /**
         * Misc uac.
         * @member {boolean|null|undefined} uac
         * @memberof hbb.Misc
         * @instance
         */
        Misc.prototype.uac = null;

        /**
         * Misc foreground_window_elevated.
         * @member {boolean|null|undefined} foreground_window_elevated
         * @memberof hbb.Misc
         * @instance
         */
        Misc.prototype.foreground_window_elevated = null;

        /**
         * Misc stop_service.
         * @member {boolean|null|undefined} stop_service
         * @memberof hbb.Misc
         * @instance
         */
        Misc.prototype.stop_service = null;

        /**
         * Misc elevation_request.
         * @member {hbb.IElevationRequest|null|undefined} elevation_request
         * @memberof hbb.Misc
         * @instance
         */
        Misc.prototype.elevation_request = null;

        /**
         * Misc elevation_response.
         * @member {string|null|undefined} elevation_response
         * @memberof hbb.Misc
         * @instance
         */
        Misc.prototype.elevation_response = null;

        /**
         * Misc portable_service_running.
         * @member {boolean|null|undefined} portable_service_running
         * @memberof hbb.Misc
         * @instance
         */
        Misc.prototype.portable_service_running = null;

        /**
         * Misc switch_sides_request.
         * @member {hbb.ISwitchSidesRequest|null|undefined} switch_sides_request
         * @memberof hbb.Misc
         * @instance
         */
        Misc.prototype.switch_sides_request = null;

        /**
         * Misc switch_back.
         * @member {hbb.ISwitchBack|null|undefined} switch_back
         * @memberof hbb.Misc
         * @instance
         */
        Misc.prototype.switch_back = null;

        /**
         * Misc change_resolution.
         * @member {hbb.IResolution|null|undefined} change_resolution
         * @memberof hbb.Misc
         * @instance
         */
        Misc.prototype.change_resolution = null;

        /**
         * Misc plugin_request.
         * @member {hbb.IPluginRequest|null|undefined} plugin_request
         * @memberof hbb.Misc
         * @instance
         */
        Misc.prototype.plugin_request = null;

        /**
         * Misc plugin_failure.
         * @member {hbb.IPluginFailure|null|undefined} plugin_failure
         * @memberof hbb.Misc
         * @instance
         */
        Misc.prototype.plugin_failure = null;

        /**
         * Misc full_speed_fps.
         * @member {number|null|undefined} full_speed_fps
         * @memberof hbb.Misc
         * @instance
         */
        Misc.prototype.full_speed_fps = null;

        /**
         * Misc auto_adjust_fps.
         * @member {number|null|undefined} auto_adjust_fps
         * @memberof hbb.Misc
         * @instance
         */
        Misc.prototype.auto_adjust_fps = null;

        /**
         * Misc client_record_status.
         * @member {boolean|null|undefined} client_record_status
         * @memberof hbb.Misc
         * @instance
         */
        Misc.prototype.client_record_status = null;

        /**
         * Misc capture_displays.
         * @member {hbb.ICaptureDisplays|null|undefined} capture_displays
         * @memberof hbb.Misc
         * @instance
         */
        Misc.prototype.capture_displays = null;

        /**
         * Misc refresh_video_display.
         * @member {number|null|undefined} refresh_video_display
         * @memberof hbb.Misc
         * @instance
         */
        Misc.prototype.refresh_video_display = null;

        /**
         * Misc toggle_virtual_display.
         * @member {hbb.IToggleVirtualDisplay|null|undefined} toggle_virtual_display
         * @memberof hbb.Misc
         * @instance
         */
        Misc.prototype.toggle_virtual_display = null;

        /**
         * Misc toggle_privacy_mode.
         * @member {hbb.ITogglePrivacyMode|null|undefined} toggle_privacy_mode
         * @memberof hbb.Misc
         * @instance
         */
        Misc.prototype.toggle_privacy_mode = null;

        /**
         * Misc supported_encoding.
         * @member {hbb.ISupportedEncoding|null|undefined} supported_encoding
         * @memberof hbb.Misc
         * @instance
         */
        Misc.prototype.supported_encoding = null;

        /**
         * Misc selected_sid.
         * @member {number|null|undefined} selected_sid
         * @memberof hbb.Misc
         * @instance
         */
        Misc.prototype.selected_sid = null;

        /**
         * Misc change_display_resolution.
         * @member {hbb.IDisplayResolution|null|undefined} change_display_resolution
         * @memberof hbb.Misc
         * @instance
         */
        Misc.prototype.change_display_resolution = null;

        /**
         * Misc message_query.
         * @member {hbb.IMessageQuery|null|undefined} message_query
         * @memberof hbb.Misc
         * @instance
         */
        Misc.prototype.message_query = null;

        /**
         * Misc follow_current_display.
         * @member {number|null|undefined} follow_current_display
         * @memberof hbb.Misc
         * @instance
         */
        Misc.prototype.follow_current_display = null;

        // OneOf field names bound to virtual getters and setters
        let $oneOfFields;

        /**
         * Misc union.
         * @member {"chat_message"|"switch_display"|"permission_info"|"option"|"audio_format"|"close_reason"|"refresh_video"|"video_received"|"back_notification"|"restart_remote_device"|"uac"|"foreground_window_elevated"|"stop_service"|"elevation_request"|"elevation_response"|"portable_service_running"|"switch_sides_request"|"switch_back"|"change_resolution"|"plugin_request"|"plugin_failure"|"full_speed_fps"|"auto_adjust_fps"|"client_record_status"|"capture_displays"|"refresh_video_display"|"toggle_virtual_display"|"toggle_privacy_mode"|"supported_encoding"|"selected_sid"|"change_display_resolution"|"message_query"|"follow_current_display"|undefined} union
         * @memberof hbb.Misc
         * @instance
         */
        Object.defineProperty(Misc.prototype, "union", {
            get: $util.oneOfGetter($oneOfFields = ["chat_message", "switch_display", "permission_info", "option", "audio_format", "close_reason", "refresh_video", "video_received", "back_notification", "restart_remote_device", "uac", "foreground_window_elevated", "stop_service", "elevation_request", "elevation_response", "portable_service_running", "switch_sides_request", "switch_back", "change_resolution", "plugin_request", "plugin_failure", "full_speed_fps", "auto_adjust_fps", "client_record_status", "capture_displays", "refresh_video_display", "toggle_virtual_display", "toggle_privacy_mode", "supported_encoding", "selected_sid", "change_display_resolution", "message_query", "follow_current_display"]),
            set: $util.oneOfSetter($oneOfFields)
        });

        /**
         * Creates a new Misc instance using the specified properties.
         * @function create
         * @memberof hbb.Misc
         * @static
         * @param {hbb.IMisc=} [properties] Properties to set
         * @returns {hbb.Misc} Misc instance
         */
        Misc.create = function create(properties) {
            return new Misc(properties);
        };

        /**
         * Encodes the specified Misc message. Does not implicitly {@link hbb.Misc.verify|verify} messages.
         * @function encode
         * @memberof hbb.Misc
         * @static
         * @param {hbb.IMisc} message Misc message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Misc.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.chat_message != null && Object.hasOwnProperty.call(message, "chat_message"))
                $root.hbb.ChatMessage.encode(message.chat_message, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim();
            if (message.switch_display != null && Object.hasOwnProperty.call(message, "switch_display"))
                $root.hbb.SwitchDisplay.encode(message.switch_display, writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim();
            if (message.permission_info != null && Object.hasOwnProperty.call(message, "permission_info"))
                $root.hbb.PermissionInfo.encode(message.permission_info, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim();
            if (message.option != null && Object.hasOwnProperty.call(message, "option"))
                $root.hbb.OptionMessage.encode(message.option, writer.uint32(/* id 7, wireType 2 =*/58).fork()).ldelim();
            if (message.audio_format != null && Object.hasOwnProperty.call(message, "audio_format"))
                $root.hbb.AudioFormat.encode(message.audio_format, writer.uint32(/* id 8, wireType 2 =*/66).fork()).ldelim();
            if (message.close_reason != null && Object.hasOwnProperty.call(message, "close_reason"))
                writer.uint32(/* id 9, wireType 2 =*/74).string(message.close_reason);
            if (message.refresh_video != null && Object.hasOwnProperty.call(message, "refresh_video"))
                writer.uint32(/* id 10, wireType 0 =*/80).bool(message.refresh_video);
            if (message.video_received != null && Object.hasOwnProperty.call(message, "video_received"))
                writer.uint32(/* id 12, wireType 0 =*/96).bool(message.video_received);
            if (message.back_notification != null && Object.hasOwnProperty.call(message, "back_notification"))
                $root.hbb.BackNotification.encode(message.back_notification, writer.uint32(/* id 13, wireType 2 =*/106).fork()).ldelim();
            if (message.restart_remote_device != null && Object.hasOwnProperty.call(message, "restart_remote_device"))
                writer.uint32(/* id 14, wireType 0 =*/112).bool(message.restart_remote_device);
            if (message.uac != null && Object.hasOwnProperty.call(message, "uac"))
                writer.uint32(/* id 15, wireType 0 =*/120).bool(message.uac);
            if (message.foreground_window_elevated != null && Object.hasOwnProperty.call(message, "foreground_window_elevated"))
                writer.uint32(/* id 16, wireType 0 =*/128).bool(message.foreground_window_elevated);
            if (message.stop_service != null && Object.hasOwnProperty.call(message, "stop_service"))
                writer.uint32(/* id 17, wireType 0 =*/136).bool(message.stop_service);
            if (message.elevation_request != null && Object.hasOwnProperty.call(message, "elevation_request"))
                $root.hbb.ElevationRequest.encode(message.elevation_request, writer.uint32(/* id 18, wireType 2 =*/146).fork()).ldelim();
            if (message.elevation_response != null && Object.hasOwnProperty.call(message, "elevation_response"))
                writer.uint32(/* id 19, wireType 2 =*/154).string(message.elevation_response);
            if (message.portable_service_running != null && Object.hasOwnProperty.call(message, "portable_service_running"))
                writer.uint32(/* id 20, wireType 0 =*/160).bool(message.portable_service_running);
            if (message.switch_sides_request != null && Object.hasOwnProperty.call(message, "switch_sides_request"))
                $root.hbb.SwitchSidesRequest.encode(message.switch_sides_request, writer.uint32(/* id 21, wireType 2 =*/170).fork()).ldelim();
            if (message.switch_back != null && Object.hasOwnProperty.call(message, "switch_back"))
                $root.hbb.SwitchBack.encode(message.switch_back, writer.uint32(/* id 22, wireType 2 =*/178).fork()).ldelim();
            if (message.change_resolution != null && Object.hasOwnProperty.call(message, "change_resolution"))
                $root.hbb.Resolution.encode(message.change_resolution, writer.uint32(/* id 24, wireType 2 =*/194).fork()).ldelim();
            if (message.plugin_request != null && Object.hasOwnProperty.call(message, "plugin_request"))
                $root.hbb.PluginRequest.encode(message.plugin_request, writer.uint32(/* id 25, wireType 2 =*/202).fork()).ldelim();
            if (message.plugin_failure != null && Object.hasOwnProperty.call(message, "plugin_failure"))
                $root.hbb.PluginFailure.encode(message.plugin_failure, writer.uint32(/* id 26, wireType 2 =*/210).fork()).ldelim();
            if (message.full_speed_fps != null && Object.hasOwnProperty.call(message, "full_speed_fps"))
                writer.uint32(/* id 27, wireType 0 =*/216).uint32(message.full_speed_fps);
            if (message.auto_adjust_fps != null && Object.hasOwnProperty.call(message, "auto_adjust_fps"))
                writer.uint32(/* id 28, wireType 0 =*/224).uint32(message.auto_adjust_fps);
            if (message.client_record_status != null && Object.hasOwnProperty.call(message, "client_record_status"))
                writer.uint32(/* id 29, wireType 0 =*/232).bool(message.client_record_status);
            if (message.capture_displays != null && Object.hasOwnProperty.call(message, "capture_displays"))
                $root.hbb.CaptureDisplays.encode(message.capture_displays, writer.uint32(/* id 30, wireType 2 =*/242).fork()).ldelim();
            if (message.refresh_video_display != null && Object.hasOwnProperty.call(message, "refresh_video_display"))
                writer.uint32(/* id 31, wireType 0 =*/248).int32(message.refresh_video_display);
            if (message.toggle_virtual_display != null && Object.hasOwnProperty.call(message, "toggle_virtual_display"))
                $root.hbb.ToggleVirtualDisplay.encode(message.toggle_virtual_display, writer.uint32(/* id 32, wireType 2 =*/258).fork()).ldelim();
            if (message.toggle_privacy_mode != null && Object.hasOwnProperty.call(message, "toggle_privacy_mode"))
                $root.hbb.TogglePrivacyMode.encode(message.toggle_privacy_mode, writer.uint32(/* id 33, wireType 2 =*/266).fork()).ldelim();
            if (message.supported_encoding != null && Object.hasOwnProperty.call(message, "supported_encoding"))
                $root.hbb.SupportedEncoding.encode(message.supported_encoding, writer.uint32(/* id 34, wireType 2 =*/274).fork()).ldelim();
            if (message.selected_sid != null && Object.hasOwnProperty.call(message, "selected_sid"))
                writer.uint32(/* id 35, wireType 0 =*/280).uint32(message.selected_sid);
            if (message.change_display_resolution != null && Object.hasOwnProperty.call(message, "change_display_resolution"))
                $root.hbb.DisplayResolution.encode(message.change_display_resolution, writer.uint32(/* id 36, wireType 2 =*/290).fork()).ldelim();
            if (message.message_query != null && Object.hasOwnProperty.call(message, "message_query"))
                $root.hbb.MessageQuery.encode(message.message_query, writer.uint32(/* id 37, wireType 2 =*/298).fork()).ldelim();
            if (message.follow_current_display != null && Object.hasOwnProperty.call(message, "follow_current_display"))
                writer.uint32(/* id 38, wireType 0 =*/304).int32(message.follow_current_display);
            return writer;
        };

        /**
         * Encodes the specified Misc message, length delimited. Does not implicitly {@link hbb.Misc.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.Misc
         * @static
         * @param {hbb.IMisc} message Misc message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Misc.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a Misc message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.Misc
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.Misc} Misc
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Misc.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.Misc();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 4: {
                        message.chat_message = $root.hbb.ChatMessage.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 5: {
                        message.switch_display = $root.hbb.SwitchDisplay.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 6: {
                        message.permission_info = $root.hbb.PermissionInfo.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 7: {
                        message.option = $root.hbb.OptionMessage.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 8: {
                        message.audio_format = $root.hbb.AudioFormat.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 9: {
                        message.close_reason = reader.string();
                        break;
                    }
                case 10: {
                        message.refresh_video = reader.bool();
                        break;
                    }
                case 12: {
                        message.video_received = reader.bool();
                        break;
                    }
                case 13: {
                        message.back_notification = $root.hbb.BackNotification.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 14: {
                        message.restart_remote_device = reader.bool();
                        break;
                    }
                case 15: {
                        message.uac = reader.bool();
                        break;
                    }
                case 16: {
                        message.foreground_window_elevated = reader.bool();
                        break;
                    }
                case 17: {
                        message.stop_service = reader.bool();
                        break;
                    }
                case 18: {
                        message.elevation_request = $root.hbb.ElevationRequest.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 19: {
                        message.elevation_response = reader.string();
                        break;
                    }
                case 20: {
                        message.portable_service_running = reader.bool();
                        break;
                    }
                case 21: {
                        message.switch_sides_request = $root.hbb.SwitchSidesRequest.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 22: {
                        message.switch_back = $root.hbb.SwitchBack.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 24: {
                        message.change_resolution = $root.hbb.Resolution.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 25: {
                        message.plugin_request = $root.hbb.PluginRequest.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 26: {
                        message.plugin_failure = $root.hbb.PluginFailure.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 27: {
                        message.full_speed_fps = reader.uint32();
                        break;
                    }
                case 28: {
                        message.auto_adjust_fps = reader.uint32();
                        break;
                    }
                case 29: {
                        message.client_record_status = reader.bool();
                        break;
                    }
                case 30: {
                        message.capture_displays = $root.hbb.CaptureDisplays.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 31: {
                        message.refresh_video_display = reader.int32();
                        break;
                    }
                case 32: {
                        message.toggle_virtual_display = $root.hbb.ToggleVirtualDisplay.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 33: {
                        message.toggle_privacy_mode = $root.hbb.TogglePrivacyMode.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 34: {
                        message.supported_encoding = $root.hbb.SupportedEncoding.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 35: {
                        message.selected_sid = reader.uint32();
                        break;
                    }
                case 36: {
                        message.change_display_resolution = $root.hbb.DisplayResolution.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 37: {
                        message.message_query = $root.hbb.MessageQuery.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 38: {
                        message.follow_current_display = reader.int32();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a Misc message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.Misc
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.Misc} Misc
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Misc.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a Misc message.
         * @function verify
         * @memberof hbb.Misc
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        Misc.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            let properties = {};
            if (message.chat_message != null && message.hasOwnProperty("chat_message")) {
                properties.union = 1;
                {
                    let error = $root.hbb.ChatMessage.verify(message.chat_message, long + 1);
                    if (error)
                        return "chat_message." + error;
                }
            }
            if (message.switch_display != null && message.hasOwnProperty("switch_display")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.SwitchDisplay.verify(message.switch_display, long + 1);
                    if (error)
                        return "switch_display." + error;
                }
            }
            if (message.permission_info != null && message.hasOwnProperty("permission_info")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.PermissionInfo.verify(message.permission_info, long + 1);
                    if (error)
                        return "permission_info." + error;
                }
            }
            if (message.option != null && message.hasOwnProperty("option")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.OptionMessage.verify(message.option, long + 1);
                    if (error)
                        return "option." + error;
                }
            }
            if (message.audio_format != null && message.hasOwnProperty("audio_format")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.AudioFormat.verify(message.audio_format, long + 1);
                    if (error)
                        return "audio_format." + error;
                }
            }
            if (message.close_reason != null && message.hasOwnProperty("close_reason")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                if (!$util.isString(message.close_reason))
                    return "close_reason: string expected";
            }
            if (message.refresh_video != null && message.hasOwnProperty("refresh_video")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                if (typeof message.refresh_video !== "boolean")
                    return "refresh_video: boolean expected";
            }
            if (message.video_received != null && message.hasOwnProperty("video_received")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                if (typeof message.video_received !== "boolean")
                    return "video_received: boolean expected";
            }
            if (message.back_notification != null && message.hasOwnProperty("back_notification")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.BackNotification.verify(message.back_notification, long + 1);
                    if (error)
                        return "back_notification." + error;
                }
            }
            if (message.restart_remote_device != null && message.hasOwnProperty("restart_remote_device")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                if (typeof message.restart_remote_device !== "boolean")
                    return "restart_remote_device: boolean expected";
            }
            if (message.uac != null && message.hasOwnProperty("uac")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                if (typeof message.uac !== "boolean")
                    return "uac: boolean expected";
            }
            if (message.foreground_window_elevated != null && message.hasOwnProperty("foreground_window_elevated")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                if (typeof message.foreground_window_elevated !== "boolean")
                    return "foreground_window_elevated: boolean expected";
            }
            if (message.stop_service != null && message.hasOwnProperty("stop_service")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                if (typeof message.stop_service !== "boolean")
                    return "stop_service: boolean expected";
            }
            if (message.elevation_request != null && message.hasOwnProperty("elevation_request")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.ElevationRequest.verify(message.elevation_request, long + 1);
                    if (error)
                        return "elevation_request." + error;
                }
            }
            if (message.elevation_response != null && message.hasOwnProperty("elevation_response")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                if (!$util.isString(message.elevation_response))
                    return "elevation_response: string expected";
            }
            if (message.portable_service_running != null && message.hasOwnProperty("portable_service_running")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                if (typeof message.portable_service_running !== "boolean")
                    return "portable_service_running: boolean expected";
            }
            if (message.switch_sides_request != null && message.hasOwnProperty("switch_sides_request")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.SwitchSidesRequest.verify(message.switch_sides_request, long + 1);
                    if (error)
                        return "switch_sides_request." + error;
                }
            }
            if (message.switch_back != null && message.hasOwnProperty("switch_back")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.SwitchBack.verify(message.switch_back, long + 1);
                    if (error)
                        return "switch_back." + error;
                }
            }
            if (message.change_resolution != null && message.hasOwnProperty("change_resolution")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.Resolution.verify(message.change_resolution, long + 1);
                    if (error)
                        return "change_resolution." + error;
                }
            }
            if (message.plugin_request != null && message.hasOwnProperty("plugin_request")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.PluginRequest.verify(message.plugin_request, long + 1);
                    if (error)
                        return "plugin_request." + error;
                }
            }
            if (message.plugin_failure != null && message.hasOwnProperty("plugin_failure")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.PluginFailure.verify(message.plugin_failure, long + 1);
                    if (error)
                        return "plugin_failure." + error;
                }
            }
            if (message.full_speed_fps != null && message.hasOwnProperty("full_speed_fps")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                if (!$util.isInteger(message.full_speed_fps))
                    return "full_speed_fps: integer expected";
            }
            if (message.auto_adjust_fps != null && message.hasOwnProperty("auto_adjust_fps")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                if (!$util.isInteger(message.auto_adjust_fps))
                    return "auto_adjust_fps: integer expected";
            }
            if (message.client_record_status != null && message.hasOwnProperty("client_record_status")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                if (typeof message.client_record_status !== "boolean")
                    return "client_record_status: boolean expected";
            }
            if (message.capture_displays != null && message.hasOwnProperty("capture_displays")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.CaptureDisplays.verify(message.capture_displays, long + 1);
                    if (error)
                        return "capture_displays." + error;
                }
            }
            if (message.refresh_video_display != null && message.hasOwnProperty("refresh_video_display")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                if (!$util.isInteger(message.refresh_video_display))
                    return "refresh_video_display: integer expected";
            }
            if (message.toggle_virtual_display != null && message.hasOwnProperty("toggle_virtual_display")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.ToggleVirtualDisplay.verify(message.toggle_virtual_display, long + 1);
                    if (error)
                        return "toggle_virtual_display." + error;
                }
            }
            if (message.toggle_privacy_mode != null && message.hasOwnProperty("toggle_privacy_mode")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.TogglePrivacyMode.verify(message.toggle_privacy_mode, long + 1);
                    if (error)
                        return "toggle_privacy_mode." + error;
                }
            }
            if (message.supported_encoding != null && message.hasOwnProperty("supported_encoding")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.SupportedEncoding.verify(message.supported_encoding, long + 1);
                    if (error)
                        return "supported_encoding." + error;
                }
            }
            if (message.selected_sid != null && message.hasOwnProperty("selected_sid")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                if (!$util.isInteger(message.selected_sid))
                    return "selected_sid: integer expected";
            }
            if (message.change_display_resolution != null && message.hasOwnProperty("change_display_resolution")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.DisplayResolution.verify(message.change_display_resolution, long + 1);
                    if (error)
                        return "change_display_resolution." + error;
                }
            }
            if (message.message_query != null && message.hasOwnProperty("message_query")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.MessageQuery.verify(message.message_query, long + 1);
                    if (error)
                        return "message_query." + error;
                }
            }
            if (message.follow_current_display != null && message.hasOwnProperty("follow_current_display")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                if (!$util.isInteger(message.follow_current_display))
                    return "follow_current_display: integer expected";
            }
            return null;
        };

        /**
         * Creates a Misc message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.Misc
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.Misc} Misc
         */
        Misc.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.Misc)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.Misc();
            if (object.chat_message != null) {
                if (typeof object.chat_message !== "object")
                    throw TypeError(".hbb.Misc.chat_message: object expected");
                message.chat_message = $root.hbb.ChatMessage.fromObject(object.chat_message, long + 1);
            }
            if (object.switch_display != null) {
                if (typeof object.switch_display !== "object")
                    throw TypeError(".hbb.Misc.switch_display: object expected");
                message.switch_display = $root.hbb.SwitchDisplay.fromObject(object.switch_display, long + 1);
            }
            if (object.permission_info != null) {
                if (typeof object.permission_info !== "object")
                    throw TypeError(".hbb.Misc.permission_info: object expected");
                message.permission_info = $root.hbb.PermissionInfo.fromObject(object.permission_info, long + 1);
            }
            if (object.option != null) {
                if (typeof object.option !== "object")
                    throw TypeError(".hbb.Misc.option: object expected");
                message.option = $root.hbb.OptionMessage.fromObject(object.option, long + 1);
            }
            if (object.audio_format != null) {
                if (typeof object.audio_format !== "object")
                    throw TypeError(".hbb.Misc.audio_format: object expected");
                message.audio_format = $root.hbb.AudioFormat.fromObject(object.audio_format, long + 1);
            }
            if (object.close_reason != null)
                message.close_reason = String(object.close_reason);
            if (object.refresh_video != null)
                message.refresh_video = Boolean(object.refresh_video);
            if (object.video_received != null)
                message.video_received = Boolean(object.video_received);
            if (object.back_notification != null) {
                if (typeof object.back_notification !== "object")
                    throw TypeError(".hbb.Misc.back_notification: object expected");
                message.back_notification = $root.hbb.BackNotification.fromObject(object.back_notification, long + 1);
            }
            if (object.restart_remote_device != null)
                message.restart_remote_device = Boolean(object.restart_remote_device);
            if (object.uac != null)
                message.uac = Boolean(object.uac);
            if (object.foreground_window_elevated != null)
                message.foreground_window_elevated = Boolean(object.foreground_window_elevated);
            if (object.stop_service != null)
                message.stop_service = Boolean(object.stop_service);
            if (object.elevation_request != null) {
                if (typeof object.elevation_request !== "object")
                    throw TypeError(".hbb.Misc.elevation_request: object expected");
                message.elevation_request = $root.hbb.ElevationRequest.fromObject(object.elevation_request, long + 1);
            }
            if (object.elevation_response != null)
                message.elevation_response = String(object.elevation_response);
            if (object.portable_service_running != null)
                message.portable_service_running = Boolean(object.portable_service_running);
            if (object.switch_sides_request != null) {
                if (typeof object.switch_sides_request !== "object")
                    throw TypeError(".hbb.Misc.switch_sides_request: object expected");
                message.switch_sides_request = $root.hbb.SwitchSidesRequest.fromObject(object.switch_sides_request, long + 1);
            }
            if (object.switch_back != null) {
                if (typeof object.switch_back !== "object")
                    throw TypeError(".hbb.Misc.switch_back: object expected");
                message.switch_back = $root.hbb.SwitchBack.fromObject(object.switch_back, long + 1);
            }
            if (object.change_resolution != null) {
                if (typeof object.change_resolution !== "object")
                    throw TypeError(".hbb.Misc.change_resolution: object expected");
                message.change_resolution = $root.hbb.Resolution.fromObject(object.change_resolution, long + 1);
            }
            if (object.plugin_request != null) {
                if (typeof object.plugin_request !== "object")
                    throw TypeError(".hbb.Misc.plugin_request: object expected");
                message.plugin_request = $root.hbb.PluginRequest.fromObject(object.plugin_request, long + 1);
            }
            if (object.plugin_failure != null) {
                if (typeof object.plugin_failure !== "object")
                    throw TypeError(".hbb.Misc.plugin_failure: object expected");
                message.plugin_failure = $root.hbb.PluginFailure.fromObject(object.plugin_failure, long + 1);
            }
            if (object.full_speed_fps != null)
                message.full_speed_fps = object.full_speed_fps >>> 0;
            if (object.auto_adjust_fps != null)
                message.auto_adjust_fps = object.auto_adjust_fps >>> 0;
            if (object.client_record_status != null)
                message.client_record_status = Boolean(object.client_record_status);
            if (object.capture_displays != null) {
                if (typeof object.capture_displays !== "object")
                    throw TypeError(".hbb.Misc.capture_displays: object expected");
                message.capture_displays = $root.hbb.CaptureDisplays.fromObject(object.capture_displays, long + 1);
            }
            if (object.refresh_video_display != null)
                message.refresh_video_display = object.refresh_video_display | 0;
            if (object.toggle_virtual_display != null) {
                if (typeof object.toggle_virtual_display !== "object")
                    throw TypeError(".hbb.Misc.toggle_virtual_display: object expected");
                message.toggle_virtual_display = $root.hbb.ToggleVirtualDisplay.fromObject(object.toggle_virtual_display, long + 1);
            }
            if (object.toggle_privacy_mode != null) {
                if (typeof object.toggle_privacy_mode !== "object")
                    throw TypeError(".hbb.Misc.toggle_privacy_mode: object expected");
                message.toggle_privacy_mode = $root.hbb.TogglePrivacyMode.fromObject(object.toggle_privacy_mode, long + 1);
            }
            if (object.supported_encoding != null) {
                if (typeof object.supported_encoding !== "object")
                    throw TypeError(".hbb.Misc.supported_encoding: object expected");
                message.supported_encoding = $root.hbb.SupportedEncoding.fromObject(object.supported_encoding, long + 1);
            }
            if (object.selected_sid != null)
                message.selected_sid = object.selected_sid >>> 0;
            if (object.change_display_resolution != null) {
                if (typeof object.change_display_resolution !== "object")
                    throw TypeError(".hbb.Misc.change_display_resolution: object expected");
                message.change_display_resolution = $root.hbb.DisplayResolution.fromObject(object.change_display_resolution, long + 1);
            }
            if (object.message_query != null) {
                if (typeof object.message_query !== "object")
                    throw TypeError(".hbb.Misc.message_query: object expected");
                message.message_query = $root.hbb.MessageQuery.fromObject(object.message_query, long + 1);
            }
            if (object.follow_current_display != null)
                message.follow_current_display = object.follow_current_display | 0;
            return message;
        };

        /**
         * Creates a plain object from a Misc message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.Misc
         * @static
         * @param {hbb.Misc} message Misc
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        Misc.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (message.chat_message != null && message.hasOwnProperty("chat_message")) {
                object.chat_message = $root.hbb.ChatMessage.toObject(message.chat_message, options);
                if (options.oneofs)
                    object.union = "chat_message";
            }
            if (message.switch_display != null && message.hasOwnProperty("switch_display")) {
                object.switch_display = $root.hbb.SwitchDisplay.toObject(message.switch_display, options);
                if (options.oneofs)
                    object.union = "switch_display";
            }
            if (message.permission_info != null && message.hasOwnProperty("permission_info")) {
                object.permission_info = $root.hbb.PermissionInfo.toObject(message.permission_info, options);
                if (options.oneofs)
                    object.union = "permission_info";
            }
            if (message.option != null && message.hasOwnProperty("option")) {
                object.option = $root.hbb.OptionMessage.toObject(message.option, options);
                if (options.oneofs)
                    object.union = "option";
            }
            if (message.audio_format != null && message.hasOwnProperty("audio_format")) {
                object.audio_format = $root.hbb.AudioFormat.toObject(message.audio_format, options);
                if (options.oneofs)
                    object.union = "audio_format";
            }
            if (message.close_reason != null && message.hasOwnProperty("close_reason")) {
                object.close_reason = message.close_reason;
                if (options.oneofs)
                    object.union = "close_reason";
            }
            if (message.refresh_video != null && message.hasOwnProperty("refresh_video")) {
                object.refresh_video = message.refresh_video;
                if (options.oneofs)
                    object.union = "refresh_video";
            }
            if (message.video_received != null && message.hasOwnProperty("video_received")) {
                object.video_received = message.video_received;
                if (options.oneofs)
                    object.union = "video_received";
            }
            if (message.back_notification != null && message.hasOwnProperty("back_notification")) {
                object.back_notification = $root.hbb.BackNotification.toObject(message.back_notification, options);
                if (options.oneofs)
                    object.union = "back_notification";
            }
            if (message.restart_remote_device != null && message.hasOwnProperty("restart_remote_device")) {
                object.restart_remote_device = message.restart_remote_device;
                if (options.oneofs)
                    object.union = "restart_remote_device";
            }
            if (message.uac != null && message.hasOwnProperty("uac")) {
                object.uac = message.uac;
                if (options.oneofs)
                    object.union = "uac";
            }
            if (message.foreground_window_elevated != null && message.hasOwnProperty("foreground_window_elevated")) {
                object.foreground_window_elevated = message.foreground_window_elevated;
                if (options.oneofs)
                    object.union = "foreground_window_elevated";
            }
            if (message.stop_service != null && message.hasOwnProperty("stop_service")) {
                object.stop_service = message.stop_service;
                if (options.oneofs)
                    object.union = "stop_service";
            }
            if (message.elevation_request != null && message.hasOwnProperty("elevation_request")) {
                object.elevation_request = $root.hbb.ElevationRequest.toObject(message.elevation_request, options);
                if (options.oneofs)
                    object.union = "elevation_request";
            }
            if (message.elevation_response != null && message.hasOwnProperty("elevation_response")) {
                object.elevation_response = message.elevation_response;
                if (options.oneofs)
                    object.union = "elevation_response";
            }
            if (message.portable_service_running != null && message.hasOwnProperty("portable_service_running")) {
                object.portable_service_running = message.portable_service_running;
                if (options.oneofs)
                    object.union = "portable_service_running";
            }
            if (message.switch_sides_request != null && message.hasOwnProperty("switch_sides_request")) {
                object.switch_sides_request = $root.hbb.SwitchSidesRequest.toObject(message.switch_sides_request, options);
                if (options.oneofs)
                    object.union = "switch_sides_request";
            }
            if (message.switch_back != null && message.hasOwnProperty("switch_back")) {
                object.switch_back = $root.hbb.SwitchBack.toObject(message.switch_back, options);
                if (options.oneofs)
                    object.union = "switch_back";
            }
            if (message.change_resolution != null && message.hasOwnProperty("change_resolution")) {
                object.change_resolution = $root.hbb.Resolution.toObject(message.change_resolution, options);
                if (options.oneofs)
                    object.union = "change_resolution";
            }
            if (message.plugin_request != null && message.hasOwnProperty("plugin_request")) {
                object.plugin_request = $root.hbb.PluginRequest.toObject(message.plugin_request, options);
                if (options.oneofs)
                    object.union = "plugin_request";
            }
            if (message.plugin_failure != null && message.hasOwnProperty("plugin_failure")) {
                object.plugin_failure = $root.hbb.PluginFailure.toObject(message.plugin_failure, options);
                if (options.oneofs)
                    object.union = "plugin_failure";
            }
            if (message.full_speed_fps != null && message.hasOwnProperty("full_speed_fps")) {
                object.full_speed_fps = message.full_speed_fps;
                if (options.oneofs)
                    object.union = "full_speed_fps";
            }
            if (message.auto_adjust_fps != null && message.hasOwnProperty("auto_adjust_fps")) {
                object.auto_adjust_fps = message.auto_adjust_fps;
                if (options.oneofs)
                    object.union = "auto_adjust_fps";
            }
            if (message.client_record_status != null && message.hasOwnProperty("client_record_status")) {
                object.client_record_status = message.client_record_status;
                if (options.oneofs)
                    object.union = "client_record_status";
            }
            if (message.capture_displays != null && message.hasOwnProperty("capture_displays")) {
                object.capture_displays = $root.hbb.CaptureDisplays.toObject(message.capture_displays, options);
                if (options.oneofs)
                    object.union = "capture_displays";
            }
            if (message.refresh_video_display != null && message.hasOwnProperty("refresh_video_display")) {
                object.refresh_video_display = message.refresh_video_display;
                if (options.oneofs)
                    object.union = "refresh_video_display";
            }
            if (message.toggle_virtual_display != null && message.hasOwnProperty("toggle_virtual_display")) {
                object.toggle_virtual_display = $root.hbb.ToggleVirtualDisplay.toObject(message.toggle_virtual_display, options);
                if (options.oneofs)
                    object.union = "toggle_virtual_display";
            }
            if (message.toggle_privacy_mode != null && message.hasOwnProperty("toggle_privacy_mode")) {
                object.toggle_privacy_mode = $root.hbb.TogglePrivacyMode.toObject(message.toggle_privacy_mode, options);
                if (options.oneofs)
                    object.union = "toggle_privacy_mode";
            }
            if (message.supported_encoding != null && message.hasOwnProperty("supported_encoding")) {
                object.supported_encoding = $root.hbb.SupportedEncoding.toObject(message.supported_encoding, options);
                if (options.oneofs)
                    object.union = "supported_encoding";
            }
            if (message.selected_sid != null && message.hasOwnProperty("selected_sid")) {
                object.selected_sid = message.selected_sid;
                if (options.oneofs)
                    object.union = "selected_sid";
            }
            if (message.change_display_resolution != null && message.hasOwnProperty("change_display_resolution")) {
                object.change_display_resolution = $root.hbb.DisplayResolution.toObject(message.change_display_resolution, options);
                if (options.oneofs)
                    object.union = "change_display_resolution";
            }
            if (message.message_query != null && message.hasOwnProperty("message_query")) {
                object.message_query = $root.hbb.MessageQuery.toObject(message.message_query, options);
                if (options.oneofs)
                    object.union = "message_query";
            }
            if (message.follow_current_display != null && message.hasOwnProperty("follow_current_display")) {
                object.follow_current_display = message.follow_current_display;
                if (options.oneofs)
                    object.union = "follow_current_display";
            }
            return object;
        };

        /**
         * Converts this Misc to JSON.
         * @function toJSON
         * @memberof hbb.Misc
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        Misc.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for Misc
         * @function getTypeUrl
         * @memberof hbb.Misc
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        Misc.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.Misc";
        };

        return Misc;
    })();

    hbb.VoiceCallRequest = (function() {

        /**
         * Properties of a VoiceCallRequest.
         * @memberof hbb
         * @interface IVoiceCallRequest
         * @property {number|Long|null} [req_timestamp] VoiceCallRequest req_timestamp
         * @property {boolean|null} [is_connect] VoiceCallRequest is_connect
         */

        /**
         * Constructs a new VoiceCallRequest.
         * @memberof hbb
         * @classdesc Represents a VoiceCallRequest.
         * @implements IVoiceCallRequest
         * @constructor
         * @param {hbb.IVoiceCallRequest=} [properties] Properties to set
         */
        function VoiceCallRequest(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * VoiceCallRequest req_timestamp.
         * @member {number|Long} req_timestamp
         * @memberof hbb.VoiceCallRequest
         * @instance
         */
        VoiceCallRequest.prototype.req_timestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * VoiceCallRequest is_connect.
         * @member {boolean} is_connect
         * @memberof hbb.VoiceCallRequest
         * @instance
         */
        VoiceCallRequest.prototype.is_connect = false;

        /**
         * Creates a new VoiceCallRequest instance using the specified properties.
         * @function create
         * @memberof hbb.VoiceCallRequest
         * @static
         * @param {hbb.IVoiceCallRequest=} [properties] Properties to set
         * @returns {hbb.VoiceCallRequest} VoiceCallRequest instance
         */
        VoiceCallRequest.create = function create(properties) {
            return new VoiceCallRequest(properties);
        };

        /**
         * Encodes the specified VoiceCallRequest message. Does not implicitly {@link hbb.VoiceCallRequest.verify|verify} messages.
         * @function encode
         * @memberof hbb.VoiceCallRequest
         * @static
         * @param {hbb.IVoiceCallRequest} message VoiceCallRequest message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        VoiceCallRequest.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.req_timestamp != null && Object.hasOwnProperty.call(message, "req_timestamp"))
                writer.uint32(/* id 1, wireType 0 =*/8).int64(message.req_timestamp);
            if (message.is_connect != null && Object.hasOwnProperty.call(message, "is_connect"))
                writer.uint32(/* id 2, wireType 0 =*/16).bool(message.is_connect);
            return writer;
        };

        /**
         * Encodes the specified VoiceCallRequest message, length delimited. Does not implicitly {@link hbb.VoiceCallRequest.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.VoiceCallRequest
         * @static
         * @param {hbb.IVoiceCallRequest} message VoiceCallRequest message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        VoiceCallRequest.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a VoiceCallRequest message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.VoiceCallRequest
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.VoiceCallRequest} VoiceCallRequest
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        VoiceCallRequest.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.VoiceCallRequest();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.req_timestamp = reader.int64();
                        break;
                    }
                case 2: {
                        message.is_connect = reader.bool();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a VoiceCallRequest message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.VoiceCallRequest
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.VoiceCallRequest} VoiceCallRequest
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        VoiceCallRequest.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a VoiceCallRequest message.
         * @function verify
         * @memberof hbb.VoiceCallRequest
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        VoiceCallRequest.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.req_timestamp != null && message.hasOwnProperty("req_timestamp"))
                if (!$util.isInteger(message.req_timestamp) && !(message.req_timestamp && $util.isInteger(message.req_timestamp.low) && $util.isInteger(message.req_timestamp.high)))
                    return "req_timestamp: integer|Long expected";
            if (message.is_connect != null && message.hasOwnProperty("is_connect"))
                if (typeof message.is_connect !== "boolean")
                    return "is_connect: boolean expected";
            return null;
        };

        /**
         * Creates a VoiceCallRequest message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.VoiceCallRequest
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.VoiceCallRequest} VoiceCallRequest
         */
        VoiceCallRequest.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.VoiceCallRequest)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.VoiceCallRequest();
            if (object.req_timestamp != null)
                if ($util.Long)
                    (message.req_timestamp = $util.Long.fromValue(object.req_timestamp)).unsigned = false;
                else if (typeof object.req_timestamp === "string")
                    message.req_timestamp = parseInt(object.req_timestamp, 10);
                else if (typeof object.req_timestamp === "number")
                    message.req_timestamp = object.req_timestamp;
                else if (typeof object.req_timestamp === "object")
                    message.req_timestamp = new $util.LongBits(object.req_timestamp.low >>> 0, object.req_timestamp.high >>> 0).toNumber();
            if (object.is_connect != null)
                message.is_connect = Boolean(object.is_connect);
            return message;
        };

        /**
         * Creates a plain object from a VoiceCallRequest message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.VoiceCallRequest
         * @static
         * @param {hbb.VoiceCallRequest} message VoiceCallRequest
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        VoiceCallRequest.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                if ($util.Long) {
                    let long = new $util.Long(0, 0, false);
                    object.req_timestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.req_timestamp = options.longs === String ? "0" : 0;
                object.is_connect = false;
            }
            if (message.req_timestamp != null && message.hasOwnProperty("req_timestamp"))
                if (typeof message.req_timestamp === "number")
                    object.req_timestamp = options.longs === String ? String(message.req_timestamp) : message.req_timestamp;
                else
                    object.req_timestamp = options.longs === String ? $util.Long.prototype.toString.call(message.req_timestamp) : options.longs === Number ? new $util.LongBits(message.req_timestamp.low >>> 0, message.req_timestamp.high >>> 0).toNumber() : message.req_timestamp;
            if (message.is_connect != null && message.hasOwnProperty("is_connect"))
                object.is_connect = message.is_connect;
            return object;
        };

        /**
         * Converts this VoiceCallRequest to JSON.
         * @function toJSON
         * @memberof hbb.VoiceCallRequest
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        VoiceCallRequest.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for VoiceCallRequest
         * @function getTypeUrl
         * @memberof hbb.VoiceCallRequest
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        VoiceCallRequest.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.VoiceCallRequest";
        };

        return VoiceCallRequest;
    })();

    hbb.VoiceCallResponse = (function() {

        /**
         * Properties of a VoiceCallResponse.
         * @memberof hbb
         * @interface IVoiceCallResponse
         * @property {boolean|null} [accepted] VoiceCallResponse accepted
         * @property {number|Long|null} [req_timestamp] VoiceCallResponse req_timestamp
         * @property {number|Long|null} [ack_timestamp] VoiceCallResponse ack_timestamp
         */

        /**
         * Constructs a new VoiceCallResponse.
         * @memberof hbb
         * @classdesc Represents a VoiceCallResponse.
         * @implements IVoiceCallResponse
         * @constructor
         * @param {hbb.IVoiceCallResponse=} [properties] Properties to set
         */
        function VoiceCallResponse(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * VoiceCallResponse accepted.
         * @member {boolean} accepted
         * @memberof hbb.VoiceCallResponse
         * @instance
         */
        VoiceCallResponse.prototype.accepted = false;

        /**
         * VoiceCallResponse req_timestamp.
         * @member {number|Long} req_timestamp
         * @memberof hbb.VoiceCallResponse
         * @instance
         */
        VoiceCallResponse.prototype.req_timestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * VoiceCallResponse ack_timestamp.
         * @member {number|Long} ack_timestamp
         * @memberof hbb.VoiceCallResponse
         * @instance
         */
        VoiceCallResponse.prototype.ack_timestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * Creates a new VoiceCallResponse instance using the specified properties.
         * @function create
         * @memberof hbb.VoiceCallResponse
         * @static
         * @param {hbb.IVoiceCallResponse=} [properties] Properties to set
         * @returns {hbb.VoiceCallResponse} VoiceCallResponse instance
         */
        VoiceCallResponse.create = function create(properties) {
            return new VoiceCallResponse(properties);
        };

        /**
         * Encodes the specified VoiceCallResponse message. Does not implicitly {@link hbb.VoiceCallResponse.verify|verify} messages.
         * @function encode
         * @memberof hbb.VoiceCallResponse
         * @static
         * @param {hbb.IVoiceCallResponse} message VoiceCallResponse message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        VoiceCallResponse.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.accepted != null && Object.hasOwnProperty.call(message, "accepted"))
                writer.uint32(/* id 1, wireType 0 =*/8).bool(message.accepted);
            if (message.req_timestamp != null && Object.hasOwnProperty.call(message, "req_timestamp"))
                writer.uint32(/* id 2, wireType 0 =*/16).int64(message.req_timestamp);
            if (message.ack_timestamp != null && Object.hasOwnProperty.call(message, "ack_timestamp"))
                writer.uint32(/* id 3, wireType 0 =*/24).int64(message.ack_timestamp);
            return writer;
        };

        /**
         * Encodes the specified VoiceCallResponse message, length delimited. Does not implicitly {@link hbb.VoiceCallResponse.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.VoiceCallResponse
         * @static
         * @param {hbb.IVoiceCallResponse} message VoiceCallResponse message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        VoiceCallResponse.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a VoiceCallResponse message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.VoiceCallResponse
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.VoiceCallResponse} VoiceCallResponse
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        VoiceCallResponse.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.VoiceCallResponse();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 1: {
                        message.accepted = reader.bool();
                        break;
                    }
                case 2: {
                        message.req_timestamp = reader.int64();
                        break;
                    }
                case 3: {
                        message.ack_timestamp = reader.int64();
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a VoiceCallResponse message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.VoiceCallResponse
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.VoiceCallResponse} VoiceCallResponse
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        VoiceCallResponse.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a VoiceCallResponse message.
         * @function verify
         * @memberof hbb.VoiceCallResponse
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        VoiceCallResponse.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            if (message.accepted != null && message.hasOwnProperty("accepted"))
                if (typeof message.accepted !== "boolean")
                    return "accepted: boolean expected";
            if (message.req_timestamp != null && message.hasOwnProperty("req_timestamp"))
                if (!$util.isInteger(message.req_timestamp) && !(message.req_timestamp && $util.isInteger(message.req_timestamp.low) && $util.isInteger(message.req_timestamp.high)))
                    return "req_timestamp: integer|Long expected";
            if (message.ack_timestamp != null && message.hasOwnProperty("ack_timestamp"))
                if (!$util.isInteger(message.ack_timestamp) && !(message.ack_timestamp && $util.isInteger(message.ack_timestamp.low) && $util.isInteger(message.ack_timestamp.high)))
                    return "ack_timestamp: integer|Long expected";
            return null;
        };

        /**
         * Creates a VoiceCallResponse message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.VoiceCallResponse
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.VoiceCallResponse} VoiceCallResponse
         */
        VoiceCallResponse.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.VoiceCallResponse)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.VoiceCallResponse();
            if (object.accepted != null)
                message.accepted = Boolean(object.accepted);
            if (object.req_timestamp != null)
                if ($util.Long)
                    (message.req_timestamp = $util.Long.fromValue(object.req_timestamp)).unsigned = false;
                else if (typeof object.req_timestamp === "string")
                    message.req_timestamp = parseInt(object.req_timestamp, 10);
                else if (typeof object.req_timestamp === "number")
                    message.req_timestamp = object.req_timestamp;
                else if (typeof object.req_timestamp === "object")
                    message.req_timestamp = new $util.LongBits(object.req_timestamp.low >>> 0, object.req_timestamp.high >>> 0).toNumber();
            if (object.ack_timestamp != null)
                if ($util.Long)
                    (message.ack_timestamp = $util.Long.fromValue(object.ack_timestamp)).unsigned = false;
                else if (typeof object.ack_timestamp === "string")
                    message.ack_timestamp = parseInt(object.ack_timestamp, 10);
                else if (typeof object.ack_timestamp === "number")
                    message.ack_timestamp = object.ack_timestamp;
                else if (typeof object.ack_timestamp === "object")
                    message.ack_timestamp = new $util.LongBits(object.ack_timestamp.low >>> 0, object.ack_timestamp.high >>> 0).toNumber();
            return message;
        };

        /**
         * Creates a plain object from a VoiceCallResponse message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.VoiceCallResponse
         * @static
         * @param {hbb.VoiceCallResponse} message VoiceCallResponse
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        VoiceCallResponse.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (options.defaults) {
                object.accepted = false;
                if ($util.Long) {
                    let long = new $util.Long(0, 0, false);
                    object.req_timestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.req_timestamp = options.longs === String ? "0" : 0;
                if ($util.Long) {
                    let long = new $util.Long(0, 0, false);
                    object.ack_timestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.ack_timestamp = options.longs === String ? "0" : 0;
            }
            if (message.accepted != null && message.hasOwnProperty("accepted"))
                object.accepted = message.accepted;
            if (message.req_timestamp != null && message.hasOwnProperty("req_timestamp"))
                if (typeof message.req_timestamp === "number")
                    object.req_timestamp = options.longs === String ? String(message.req_timestamp) : message.req_timestamp;
                else
                    object.req_timestamp = options.longs === String ? $util.Long.prototype.toString.call(message.req_timestamp) : options.longs === Number ? new $util.LongBits(message.req_timestamp.low >>> 0, message.req_timestamp.high >>> 0).toNumber() : message.req_timestamp;
            if (message.ack_timestamp != null && message.hasOwnProperty("ack_timestamp"))
                if (typeof message.ack_timestamp === "number")
                    object.ack_timestamp = options.longs === String ? String(message.ack_timestamp) : message.ack_timestamp;
                else
                    object.ack_timestamp = options.longs === String ? $util.Long.prototype.toString.call(message.ack_timestamp) : options.longs === Number ? new $util.LongBits(message.ack_timestamp.low >>> 0, message.ack_timestamp.high >>> 0).toNumber() : message.ack_timestamp;
            return object;
        };

        /**
         * Converts this VoiceCallResponse to JSON.
         * @function toJSON
         * @memberof hbb.VoiceCallResponse
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        VoiceCallResponse.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for VoiceCallResponse
         * @function getTypeUrl
         * @memberof hbb.VoiceCallResponse
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        VoiceCallResponse.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.VoiceCallResponse";
        };

        return VoiceCallResponse;
    })();

    hbb.Message = (function() {

        /**
         * Properties of a Message.
         * @memberof hbb
         * @interface IMessage
         * @property {hbb.ISignedId|null} [signed_id] Message signed_id
         * @property {hbb.IPublicKey|null} [public_key] Message public_key
         * @property {hbb.ITestDelay|null} [test_delay] Message test_delay
         * @property {hbb.IVideoFrame|null} [video_frame] Message video_frame
         * @property {hbb.ILoginRequest|null} [login_request] Message login_request
         * @property {hbb.ILoginResponse|null} [login_response] Message login_response
         * @property {hbb.IHash|null} [hash] Message hash
         * @property {hbb.IMouseEvent|null} [mouse_event] Message mouse_event
         * @property {hbb.IAudioFrame|null} [audio_frame] Message audio_frame
         * @property {hbb.ICursorData|null} [cursor_data] Message cursor_data
         * @property {hbb.ICursorPosition|null} [cursor_position] Message cursor_position
         * @property {number|Long|null} [cursor_id] Message cursor_id
         * @property {hbb.IKeyEvent|null} [key_event] Message key_event
         * @property {hbb.IClipboard|null} [clipboard] Message clipboard
         * @property {hbb.IFileAction|null} [file_action] Message file_action
         * @property {hbb.IFileResponse|null} [file_response] Message file_response
         * @property {hbb.IMisc|null} [misc] Message misc
         * @property {hbb.ICliprdr|null} [cliprdr] Message cliprdr
         * @property {hbb.IMessageBox|null} [message_box] Message message_box
         * @property {hbb.ISwitchSidesResponse|null} [switch_sides_response] Message switch_sides_response
         * @property {hbb.IVoiceCallRequest|null} [voice_call_request] Message voice_call_request
         * @property {hbb.IVoiceCallResponse|null} [voice_call_response] Message voice_call_response
         * @property {hbb.IPeerInfo|null} [peer_info] Message peer_info
         * @property {hbb.IPointerDeviceEvent|null} [pointer_device_event] Message pointer_device_event
         * @property {hbb.IAuth2FA|null} [auth_2fa] Message auth_2fa
         * @property {hbb.IMultiClipboards|null} [multi_clipboards] Message multi_clipboards
         */

        /**
         * Constructs a new Message.
         * @memberof hbb
         * @classdesc Represents a Message.
         * @implements IMessage
         * @constructor
         * @param {hbb.IMessage=} [properties] Properties to set
         */
        function Message(properties) {
            if (properties)
                for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null && keys[i] !== "__proto__")
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * Message signed_id.
         * @member {hbb.ISignedId|null|undefined} signed_id
         * @memberof hbb.Message
         * @instance
         */
        Message.prototype.signed_id = null;

        /**
         * Message public_key.
         * @member {hbb.IPublicKey|null|undefined} public_key
         * @memberof hbb.Message
         * @instance
         */
        Message.prototype.public_key = null;

        /**
         * Message test_delay.
         * @member {hbb.ITestDelay|null|undefined} test_delay
         * @memberof hbb.Message
         * @instance
         */
        Message.prototype.test_delay = null;

        /**
         * Message video_frame.
         * @member {hbb.IVideoFrame|null|undefined} video_frame
         * @memberof hbb.Message
         * @instance
         */
        Message.prototype.video_frame = null;

        /**
         * Message login_request.
         * @member {hbb.ILoginRequest|null|undefined} login_request
         * @memberof hbb.Message
         * @instance
         */
        Message.prototype.login_request = null;

        /**
         * Message login_response.
         * @member {hbb.ILoginResponse|null|undefined} login_response
         * @memberof hbb.Message
         * @instance
         */
        Message.prototype.login_response = null;

        /**
         * Message hash.
         * @member {hbb.IHash|null|undefined} hash
         * @memberof hbb.Message
         * @instance
         */
        Message.prototype.hash = null;

        /**
         * Message mouse_event.
         * @member {hbb.IMouseEvent|null|undefined} mouse_event
         * @memberof hbb.Message
         * @instance
         */
        Message.prototype.mouse_event = null;

        /**
         * Message audio_frame.
         * @member {hbb.IAudioFrame|null|undefined} audio_frame
         * @memberof hbb.Message
         * @instance
         */
        Message.prototype.audio_frame = null;

        /**
         * Message cursor_data.
         * @member {hbb.ICursorData|null|undefined} cursor_data
         * @memberof hbb.Message
         * @instance
         */
        Message.prototype.cursor_data = null;

        /**
         * Message cursor_position.
         * @member {hbb.ICursorPosition|null|undefined} cursor_position
         * @memberof hbb.Message
         * @instance
         */
        Message.prototype.cursor_position = null;

        /**
         * Message cursor_id.
         * @member {number|Long|null|undefined} cursor_id
         * @memberof hbb.Message
         * @instance
         */
        Message.prototype.cursor_id = null;

        /**
         * Message key_event.
         * @member {hbb.IKeyEvent|null|undefined} key_event
         * @memberof hbb.Message
         * @instance
         */
        Message.prototype.key_event = null;

        /**
         * Message clipboard.
         * @member {hbb.IClipboard|null|undefined} clipboard
         * @memberof hbb.Message
         * @instance
         */
        Message.prototype.clipboard = null;

        /**
         * Message file_action.
         * @member {hbb.IFileAction|null|undefined} file_action
         * @memberof hbb.Message
         * @instance
         */
        Message.prototype.file_action = null;

        /**
         * Message file_response.
         * @member {hbb.IFileResponse|null|undefined} file_response
         * @memberof hbb.Message
         * @instance
         */
        Message.prototype.file_response = null;

        /**
         * Message misc.
         * @member {hbb.IMisc|null|undefined} misc
         * @memberof hbb.Message
         * @instance
         */
        Message.prototype.misc = null;

        /**
         * Message cliprdr.
         * @member {hbb.ICliprdr|null|undefined} cliprdr
         * @memberof hbb.Message
         * @instance
         */
        Message.prototype.cliprdr = null;

        /**
         * Message message_box.
         * @member {hbb.IMessageBox|null|undefined} message_box
         * @memberof hbb.Message
         * @instance
         */
        Message.prototype.message_box = null;

        /**
         * Message switch_sides_response.
         * @member {hbb.ISwitchSidesResponse|null|undefined} switch_sides_response
         * @memberof hbb.Message
         * @instance
         */
        Message.prototype.switch_sides_response = null;

        /**
         * Message voice_call_request.
         * @member {hbb.IVoiceCallRequest|null|undefined} voice_call_request
         * @memberof hbb.Message
         * @instance
         */
        Message.prototype.voice_call_request = null;

        /**
         * Message voice_call_response.
         * @member {hbb.IVoiceCallResponse|null|undefined} voice_call_response
         * @memberof hbb.Message
         * @instance
         */
        Message.prototype.voice_call_response = null;

        /**
         * Message peer_info.
         * @member {hbb.IPeerInfo|null|undefined} peer_info
         * @memberof hbb.Message
         * @instance
         */
        Message.prototype.peer_info = null;

        /**
         * Message pointer_device_event.
         * @member {hbb.IPointerDeviceEvent|null|undefined} pointer_device_event
         * @memberof hbb.Message
         * @instance
         */
        Message.prototype.pointer_device_event = null;

        /**
         * Message auth_2fa.
         * @member {hbb.IAuth2FA|null|undefined} auth_2fa
         * @memberof hbb.Message
         * @instance
         */
        Message.prototype.auth_2fa = null;

        /**
         * Message multi_clipboards.
         * @member {hbb.IMultiClipboards|null|undefined} multi_clipboards
         * @memberof hbb.Message
         * @instance
         */
        Message.prototype.multi_clipboards = null;

        // OneOf field names bound to virtual getters and setters
        let $oneOfFields;

        /**
         * Message union.
         * @member {"signed_id"|"public_key"|"test_delay"|"video_frame"|"login_request"|"login_response"|"hash"|"mouse_event"|"audio_frame"|"cursor_data"|"cursor_position"|"cursor_id"|"key_event"|"clipboard"|"file_action"|"file_response"|"misc"|"cliprdr"|"message_box"|"switch_sides_response"|"voice_call_request"|"voice_call_response"|"peer_info"|"pointer_device_event"|"auth_2fa"|"multi_clipboards"|undefined} union
         * @memberof hbb.Message
         * @instance
         */
        Object.defineProperty(Message.prototype, "union", {
            get: $util.oneOfGetter($oneOfFields = ["signed_id", "public_key", "test_delay", "video_frame", "login_request", "login_response", "hash", "mouse_event", "audio_frame", "cursor_data", "cursor_position", "cursor_id", "key_event", "clipboard", "file_action", "file_response", "misc", "cliprdr", "message_box", "switch_sides_response", "voice_call_request", "voice_call_response", "peer_info", "pointer_device_event", "auth_2fa", "multi_clipboards"]),
            set: $util.oneOfSetter($oneOfFields)
        });

        /**
         * Creates a new Message instance using the specified properties.
         * @function create
         * @memberof hbb.Message
         * @static
         * @param {hbb.IMessage=} [properties] Properties to set
         * @returns {hbb.Message} Message instance
         */
        Message.create = function create(properties) {
            return new Message(properties);
        };

        /**
         * Encodes the specified Message message. Does not implicitly {@link hbb.Message.verify|verify} messages.
         * @function encode
         * @memberof hbb.Message
         * @static
         * @param {hbb.IMessage} message Message message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Message.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.signed_id != null && Object.hasOwnProperty.call(message, "signed_id"))
                $root.hbb.SignedId.encode(message.signed_id, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
            if (message.public_key != null && Object.hasOwnProperty.call(message, "public_key"))
                $root.hbb.PublicKey.encode(message.public_key, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim();
            if (message.test_delay != null && Object.hasOwnProperty.call(message, "test_delay"))
                $root.hbb.TestDelay.encode(message.test_delay, writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim();
            if (message.video_frame != null && Object.hasOwnProperty.call(message, "video_frame"))
                $root.hbb.VideoFrame.encode(message.video_frame, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim();
            if (message.login_request != null && Object.hasOwnProperty.call(message, "login_request"))
                $root.hbb.LoginRequest.encode(message.login_request, writer.uint32(/* id 7, wireType 2 =*/58).fork()).ldelim();
            if (message.login_response != null && Object.hasOwnProperty.call(message, "login_response"))
                $root.hbb.LoginResponse.encode(message.login_response, writer.uint32(/* id 8, wireType 2 =*/66).fork()).ldelim();
            if (message.hash != null && Object.hasOwnProperty.call(message, "hash"))
                $root.hbb.Hash.encode(message.hash, writer.uint32(/* id 9, wireType 2 =*/74).fork()).ldelim();
            if (message.mouse_event != null && Object.hasOwnProperty.call(message, "mouse_event"))
                $root.hbb.MouseEvent.encode(message.mouse_event, writer.uint32(/* id 10, wireType 2 =*/82).fork()).ldelim();
            if (message.audio_frame != null && Object.hasOwnProperty.call(message, "audio_frame"))
                $root.hbb.AudioFrame.encode(message.audio_frame, writer.uint32(/* id 11, wireType 2 =*/90).fork()).ldelim();
            if (message.cursor_data != null && Object.hasOwnProperty.call(message, "cursor_data"))
                $root.hbb.CursorData.encode(message.cursor_data, writer.uint32(/* id 12, wireType 2 =*/98).fork()).ldelim();
            if (message.cursor_position != null && Object.hasOwnProperty.call(message, "cursor_position"))
                $root.hbb.CursorPosition.encode(message.cursor_position, writer.uint32(/* id 13, wireType 2 =*/106).fork()).ldelim();
            if (message.cursor_id != null && Object.hasOwnProperty.call(message, "cursor_id"))
                writer.uint32(/* id 14, wireType 0 =*/112).uint64(message.cursor_id);
            if (message.key_event != null && Object.hasOwnProperty.call(message, "key_event"))
                $root.hbb.KeyEvent.encode(message.key_event, writer.uint32(/* id 15, wireType 2 =*/122).fork()).ldelim();
            if (message.clipboard != null && Object.hasOwnProperty.call(message, "clipboard"))
                $root.hbb.Clipboard.encode(message.clipboard, writer.uint32(/* id 16, wireType 2 =*/130).fork()).ldelim();
            if (message.file_action != null && Object.hasOwnProperty.call(message, "file_action"))
                $root.hbb.FileAction.encode(message.file_action, writer.uint32(/* id 17, wireType 2 =*/138).fork()).ldelim();
            if (message.file_response != null && Object.hasOwnProperty.call(message, "file_response"))
                $root.hbb.FileResponse.encode(message.file_response, writer.uint32(/* id 18, wireType 2 =*/146).fork()).ldelim();
            if (message.misc != null && Object.hasOwnProperty.call(message, "misc"))
                $root.hbb.Misc.encode(message.misc, writer.uint32(/* id 19, wireType 2 =*/154).fork()).ldelim();
            if (message.cliprdr != null && Object.hasOwnProperty.call(message, "cliprdr"))
                $root.hbb.Cliprdr.encode(message.cliprdr, writer.uint32(/* id 20, wireType 2 =*/162).fork()).ldelim();
            if (message.message_box != null && Object.hasOwnProperty.call(message, "message_box"))
                $root.hbb.MessageBox.encode(message.message_box, writer.uint32(/* id 21, wireType 2 =*/170).fork()).ldelim();
            if (message.switch_sides_response != null && Object.hasOwnProperty.call(message, "switch_sides_response"))
                $root.hbb.SwitchSidesResponse.encode(message.switch_sides_response, writer.uint32(/* id 22, wireType 2 =*/178).fork()).ldelim();
            if (message.voice_call_request != null && Object.hasOwnProperty.call(message, "voice_call_request"))
                $root.hbb.VoiceCallRequest.encode(message.voice_call_request, writer.uint32(/* id 23, wireType 2 =*/186).fork()).ldelim();
            if (message.voice_call_response != null && Object.hasOwnProperty.call(message, "voice_call_response"))
                $root.hbb.VoiceCallResponse.encode(message.voice_call_response, writer.uint32(/* id 24, wireType 2 =*/194).fork()).ldelim();
            if (message.peer_info != null && Object.hasOwnProperty.call(message, "peer_info"))
                $root.hbb.PeerInfo.encode(message.peer_info, writer.uint32(/* id 25, wireType 2 =*/202).fork()).ldelim();
            if (message.pointer_device_event != null && Object.hasOwnProperty.call(message, "pointer_device_event"))
                $root.hbb.PointerDeviceEvent.encode(message.pointer_device_event, writer.uint32(/* id 26, wireType 2 =*/210).fork()).ldelim();
            if (message.auth_2fa != null && Object.hasOwnProperty.call(message, "auth_2fa"))
                $root.hbb.Auth2FA.encode(message.auth_2fa, writer.uint32(/* id 27, wireType 2 =*/218).fork()).ldelim();
            if (message.multi_clipboards != null && Object.hasOwnProperty.call(message, "multi_clipboards"))
                $root.hbb.MultiClipboards.encode(message.multi_clipboards, writer.uint32(/* id 28, wireType 2 =*/226).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified Message message, length delimited. Does not implicitly {@link hbb.Message.verify|verify} messages.
         * @function encodeDelimited
         * @memberof hbb.Message
         * @static
         * @param {hbb.IMessage} message Message message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Message.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a Message message from the specified reader or buffer.
         * @function decode
         * @memberof hbb.Message
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {hbb.Message} Message
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Message.decode = function decode(reader, length, error, long) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            if (long === undefined)
                long = 0;
            if (long > $Reader.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let end = length === undefined ? reader.len : reader.pos + length, message = new $root.hbb.Message();
            while (reader.pos < end) {
                let tag = reader.uint32();
                if (tag === error)
                    break;
                switch (tag >>> 3) {
                case 3: {
                        message.signed_id = $root.hbb.SignedId.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 4: {
                        message.public_key = $root.hbb.PublicKey.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 5: {
                        message.test_delay = $root.hbb.TestDelay.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 6: {
                        message.video_frame = $root.hbb.VideoFrame.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 7: {
                        message.login_request = $root.hbb.LoginRequest.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 8: {
                        message.login_response = $root.hbb.LoginResponse.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 9: {
                        message.hash = $root.hbb.Hash.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 10: {
                        message.mouse_event = $root.hbb.MouseEvent.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 11: {
                        message.audio_frame = $root.hbb.AudioFrame.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 12: {
                        message.cursor_data = $root.hbb.CursorData.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 13: {
                        message.cursor_position = $root.hbb.CursorPosition.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 14: {
                        message.cursor_id = reader.uint64();
                        break;
                    }
                case 15: {
                        message.key_event = $root.hbb.KeyEvent.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 16: {
                        message.clipboard = $root.hbb.Clipboard.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 17: {
                        message.file_action = $root.hbb.FileAction.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 18: {
                        message.file_response = $root.hbb.FileResponse.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 19: {
                        message.misc = $root.hbb.Misc.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 20: {
                        message.cliprdr = $root.hbb.Cliprdr.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 21: {
                        message.message_box = $root.hbb.MessageBox.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 22: {
                        message.switch_sides_response = $root.hbb.SwitchSidesResponse.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 23: {
                        message.voice_call_request = $root.hbb.VoiceCallRequest.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 24: {
                        message.voice_call_response = $root.hbb.VoiceCallResponse.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 25: {
                        message.peer_info = $root.hbb.PeerInfo.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 26: {
                        message.pointer_device_event = $root.hbb.PointerDeviceEvent.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 27: {
                        message.auth_2fa = $root.hbb.Auth2FA.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                case 28: {
                        message.multi_clipboards = $root.hbb.MultiClipboards.decode(reader, reader.uint32(), undefined, long + 1);
                        break;
                    }
                default:
                    reader.skipType(tag & 7, long);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a Message message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof hbb.Message
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {hbb.Message} Message
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Message.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a Message message.
         * @function verify
         * @memberof hbb.Message
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        Message.verify = function verify(message, long) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                return "maximum nesting depth exceeded";
            let properties = {};
            if (message.signed_id != null && message.hasOwnProperty("signed_id")) {
                properties.union = 1;
                {
                    let error = $root.hbb.SignedId.verify(message.signed_id, long + 1);
                    if (error)
                        return "signed_id." + error;
                }
            }
            if (message.public_key != null && message.hasOwnProperty("public_key")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.PublicKey.verify(message.public_key, long + 1);
                    if (error)
                        return "public_key." + error;
                }
            }
            if (message.test_delay != null && message.hasOwnProperty("test_delay")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.TestDelay.verify(message.test_delay, long + 1);
                    if (error)
                        return "test_delay." + error;
                }
            }
            if (message.video_frame != null && message.hasOwnProperty("video_frame")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.VideoFrame.verify(message.video_frame, long + 1);
                    if (error)
                        return "video_frame." + error;
                }
            }
            if (message.login_request != null && message.hasOwnProperty("login_request")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.LoginRequest.verify(message.login_request, long + 1);
                    if (error)
                        return "login_request." + error;
                }
            }
            if (message.login_response != null && message.hasOwnProperty("login_response")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.LoginResponse.verify(message.login_response, long + 1);
                    if (error)
                        return "login_response." + error;
                }
            }
            if (message.hash != null && message.hasOwnProperty("hash")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.Hash.verify(message.hash, long + 1);
                    if (error)
                        return "hash." + error;
                }
            }
            if (message.mouse_event != null && message.hasOwnProperty("mouse_event")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.MouseEvent.verify(message.mouse_event, long + 1);
                    if (error)
                        return "mouse_event." + error;
                }
            }
            if (message.audio_frame != null && message.hasOwnProperty("audio_frame")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.AudioFrame.verify(message.audio_frame, long + 1);
                    if (error)
                        return "audio_frame." + error;
                }
            }
            if (message.cursor_data != null && message.hasOwnProperty("cursor_data")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.CursorData.verify(message.cursor_data, long + 1);
                    if (error)
                        return "cursor_data." + error;
                }
            }
            if (message.cursor_position != null && message.hasOwnProperty("cursor_position")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.CursorPosition.verify(message.cursor_position, long + 1);
                    if (error)
                        return "cursor_position." + error;
                }
            }
            if (message.cursor_id != null && message.hasOwnProperty("cursor_id")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                if (!$util.isInteger(message.cursor_id) && !(message.cursor_id && $util.isInteger(message.cursor_id.low) && $util.isInteger(message.cursor_id.high)))
                    return "cursor_id: integer|Long expected";
            }
            if (message.key_event != null && message.hasOwnProperty("key_event")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.KeyEvent.verify(message.key_event, long + 1);
                    if (error)
                        return "key_event." + error;
                }
            }
            if (message.clipboard != null && message.hasOwnProperty("clipboard")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.Clipboard.verify(message.clipboard, long + 1);
                    if (error)
                        return "clipboard." + error;
                }
            }
            if (message.file_action != null && message.hasOwnProperty("file_action")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.FileAction.verify(message.file_action, long + 1);
                    if (error)
                        return "file_action." + error;
                }
            }
            if (message.file_response != null && message.hasOwnProperty("file_response")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.FileResponse.verify(message.file_response, long + 1);
                    if (error)
                        return "file_response." + error;
                }
            }
            if (message.misc != null && message.hasOwnProperty("misc")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.Misc.verify(message.misc, long + 1);
                    if (error)
                        return "misc." + error;
                }
            }
            if (message.cliprdr != null && message.hasOwnProperty("cliprdr")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.Cliprdr.verify(message.cliprdr, long + 1);
                    if (error)
                        return "cliprdr." + error;
                }
            }
            if (message.message_box != null && message.hasOwnProperty("message_box")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.MessageBox.verify(message.message_box, long + 1);
                    if (error)
                        return "message_box." + error;
                }
            }
            if (message.switch_sides_response != null && message.hasOwnProperty("switch_sides_response")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.SwitchSidesResponse.verify(message.switch_sides_response, long + 1);
                    if (error)
                        return "switch_sides_response." + error;
                }
            }
            if (message.voice_call_request != null && message.hasOwnProperty("voice_call_request")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.VoiceCallRequest.verify(message.voice_call_request, long + 1);
                    if (error)
                        return "voice_call_request." + error;
                }
            }
            if (message.voice_call_response != null && message.hasOwnProperty("voice_call_response")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.VoiceCallResponse.verify(message.voice_call_response, long + 1);
                    if (error)
                        return "voice_call_response." + error;
                }
            }
            if (message.peer_info != null && message.hasOwnProperty("peer_info")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.PeerInfo.verify(message.peer_info, long + 1);
                    if (error)
                        return "peer_info." + error;
                }
            }
            if (message.pointer_device_event != null && message.hasOwnProperty("pointer_device_event")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.PointerDeviceEvent.verify(message.pointer_device_event, long + 1);
                    if (error)
                        return "pointer_device_event." + error;
                }
            }
            if (message.auth_2fa != null && message.hasOwnProperty("auth_2fa")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.Auth2FA.verify(message.auth_2fa, long + 1);
                    if (error)
                        return "auth_2fa." + error;
                }
            }
            if (message.multi_clipboards != null && message.hasOwnProperty("multi_clipboards")) {
                if (properties.union === 1)
                    return "union: multiple values";
                properties.union = 1;
                {
                    let error = $root.hbb.MultiClipboards.verify(message.multi_clipboards, long + 1);
                    if (error)
                        return "multi_clipboards." + error;
                }
            }
            return null;
        };

        /**
         * Creates a Message message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof hbb.Message
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {hbb.Message} Message
         */
        Message.fromObject = function fromObject(object, long) {
            if (object instanceof $root.hbb.Message)
                return object;
            if (long === undefined)
                long = 0;
            if (long > $util.recursionLimit)
                throw Error("maximum nesting depth exceeded");
            let message = new $root.hbb.Message();
            if (object.signed_id != null) {
                if (typeof object.signed_id !== "object")
                    throw TypeError(".hbb.Message.signed_id: object expected");
                message.signed_id = $root.hbb.SignedId.fromObject(object.signed_id, long + 1);
            }
            if (object.public_key != null) {
                if (typeof object.public_key !== "object")
                    throw TypeError(".hbb.Message.public_key: object expected");
                message.public_key = $root.hbb.PublicKey.fromObject(object.public_key, long + 1);
            }
            if (object.test_delay != null) {
                if (typeof object.test_delay !== "object")
                    throw TypeError(".hbb.Message.test_delay: object expected");
                message.test_delay = $root.hbb.TestDelay.fromObject(object.test_delay, long + 1);
            }
            if (object.video_frame != null) {
                if (typeof object.video_frame !== "object")
                    throw TypeError(".hbb.Message.video_frame: object expected");
                message.video_frame = $root.hbb.VideoFrame.fromObject(object.video_frame, long + 1);
            }
            if (object.login_request != null) {
                if (typeof object.login_request !== "object")
                    throw TypeError(".hbb.Message.login_request: object expected");
                message.login_request = $root.hbb.LoginRequest.fromObject(object.login_request, long + 1);
            }
            if (object.login_response != null) {
                if (typeof object.login_response !== "object")
                    throw TypeError(".hbb.Message.login_response: object expected");
                message.login_response = $root.hbb.LoginResponse.fromObject(object.login_response, long + 1);
            }
            if (object.hash != null) {
                if (typeof object.hash !== "object")
                    throw TypeError(".hbb.Message.hash: object expected");
                message.hash = $root.hbb.Hash.fromObject(object.hash, long + 1);
            }
            if (object.mouse_event != null) {
                if (typeof object.mouse_event !== "object")
                    throw TypeError(".hbb.Message.mouse_event: object expected");
                message.mouse_event = $root.hbb.MouseEvent.fromObject(object.mouse_event, long + 1);
            }
            if (object.audio_frame != null) {
                if (typeof object.audio_frame !== "object")
                    throw TypeError(".hbb.Message.audio_frame: object expected");
                message.audio_frame = $root.hbb.AudioFrame.fromObject(object.audio_frame, long + 1);
            }
            if (object.cursor_data != null) {
                if (typeof object.cursor_data !== "object")
                    throw TypeError(".hbb.Message.cursor_data: object expected");
                message.cursor_data = $root.hbb.CursorData.fromObject(object.cursor_data, long + 1);
            }
            if (object.cursor_position != null) {
                if (typeof object.cursor_position !== "object")
                    throw TypeError(".hbb.Message.cursor_position: object expected");
                message.cursor_position = $root.hbb.CursorPosition.fromObject(object.cursor_position, long + 1);
            }
            if (object.cursor_id != null)
                if ($util.Long)
                    (message.cursor_id = $util.Long.fromValue(object.cursor_id)).unsigned = true;
                else if (typeof object.cursor_id === "string")
                    message.cursor_id = parseInt(object.cursor_id, 10);
                else if (typeof object.cursor_id === "number")
                    message.cursor_id = object.cursor_id;
                else if (typeof object.cursor_id === "object")
                    message.cursor_id = new $util.LongBits(object.cursor_id.low >>> 0, object.cursor_id.high >>> 0).toNumber(true);
            if (object.key_event != null) {
                if (typeof object.key_event !== "object")
                    throw TypeError(".hbb.Message.key_event: object expected");
                message.key_event = $root.hbb.KeyEvent.fromObject(object.key_event, long + 1);
            }
            if (object.clipboard != null) {
                if (typeof object.clipboard !== "object")
                    throw TypeError(".hbb.Message.clipboard: object expected");
                message.clipboard = $root.hbb.Clipboard.fromObject(object.clipboard, long + 1);
            }
            if (object.file_action != null) {
                if (typeof object.file_action !== "object")
                    throw TypeError(".hbb.Message.file_action: object expected");
                message.file_action = $root.hbb.FileAction.fromObject(object.file_action, long + 1);
            }
            if (object.file_response != null) {
                if (typeof object.file_response !== "object")
                    throw TypeError(".hbb.Message.file_response: object expected");
                message.file_response = $root.hbb.FileResponse.fromObject(object.file_response, long + 1);
            }
            if (object.misc != null) {
                if (typeof object.misc !== "object")
                    throw TypeError(".hbb.Message.misc: object expected");
                message.misc = $root.hbb.Misc.fromObject(object.misc, long + 1);
            }
            if (object.cliprdr != null) {
                if (typeof object.cliprdr !== "object")
                    throw TypeError(".hbb.Message.cliprdr: object expected");
                message.cliprdr = $root.hbb.Cliprdr.fromObject(object.cliprdr, long + 1);
            }
            if (object.message_box != null) {
                if (typeof object.message_box !== "object")
                    throw TypeError(".hbb.Message.message_box: object expected");
                message.message_box = $root.hbb.MessageBox.fromObject(object.message_box, long + 1);
            }
            if (object.switch_sides_response != null) {
                if (typeof object.switch_sides_response !== "object")
                    throw TypeError(".hbb.Message.switch_sides_response: object expected");
                message.switch_sides_response = $root.hbb.SwitchSidesResponse.fromObject(object.switch_sides_response, long + 1);
            }
            if (object.voice_call_request != null) {
                if (typeof object.voice_call_request !== "object")
                    throw TypeError(".hbb.Message.voice_call_request: object expected");
                message.voice_call_request = $root.hbb.VoiceCallRequest.fromObject(object.voice_call_request, long + 1);
            }
            if (object.voice_call_response != null) {
                if (typeof object.voice_call_response !== "object")
                    throw TypeError(".hbb.Message.voice_call_response: object expected");
                message.voice_call_response = $root.hbb.VoiceCallResponse.fromObject(object.voice_call_response, long + 1);
            }
            if (object.peer_info != null) {
                if (typeof object.peer_info !== "object")
                    throw TypeError(".hbb.Message.peer_info: object expected");
                message.peer_info = $root.hbb.PeerInfo.fromObject(object.peer_info, long + 1);
            }
            if (object.pointer_device_event != null) {
                if (typeof object.pointer_device_event !== "object")
                    throw TypeError(".hbb.Message.pointer_device_event: object expected");
                message.pointer_device_event = $root.hbb.PointerDeviceEvent.fromObject(object.pointer_device_event, long + 1);
            }
            if (object.auth_2fa != null) {
                if (typeof object.auth_2fa !== "object")
                    throw TypeError(".hbb.Message.auth_2fa: object expected");
                message.auth_2fa = $root.hbb.Auth2FA.fromObject(object.auth_2fa, long + 1);
            }
            if (object.multi_clipboards != null) {
                if (typeof object.multi_clipboards !== "object")
                    throw TypeError(".hbb.Message.multi_clipboards: object expected");
                message.multi_clipboards = $root.hbb.MultiClipboards.fromObject(object.multi_clipboards, long + 1);
            }
            return message;
        };

        /**
         * Creates a plain object from a Message message. Also converts values to other types if specified.
         * @function toObject
         * @memberof hbb.Message
         * @static
         * @param {hbb.Message} message Message
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        Message.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            let object = {};
            if (message.signed_id != null && message.hasOwnProperty("signed_id")) {
                object.signed_id = $root.hbb.SignedId.toObject(message.signed_id, options);
                if (options.oneofs)
                    object.union = "signed_id";
            }
            if (message.public_key != null && message.hasOwnProperty("public_key")) {
                object.public_key = $root.hbb.PublicKey.toObject(message.public_key, options);
                if (options.oneofs)
                    object.union = "public_key";
            }
            if (message.test_delay != null && message.hasOwnProperty("test_delay")) {
                object.test_delay = $root.hbb.TestDelay.toObject(message.test_delay, options);
                if (options.oneofs)
                    object.union = "test_delay";
            }
            if (message.video_frame != null && message.hasOwnProperty("video_frame")) {
                object.video_frame = $root.hbb.VideoFrame.toObject(message.video_frame, options);
                if (options.oneofs)
                    object.union = "video_frame";
            }
            if (message.login_request != null && message.hasOwnProperty("login_request")) {
                object.login_request = $root.hbb.LoginRequest.toObject(message.login_request, options);
                if (options.oneofs)
                    object.union = "login_request";
            }
            if (message.login_response != null && message.hasOwnProperty("login_response")) {
                object.login_response = $root.hbb.LoginResponse.toObject(message.login_response, options);
                if (options.oneofs)
                    object.union = "login_response";
            }
            if (message.hash != null && message.hasOwnProperty("hash")) {
                object.hash = $root.hbb.Hash.toObject(message.hash, options);
                if (options.oneofs)
                    object.union = "hash";
            }
            if (message.mouse_event != null && message.hasOwnProperty("mouse_event")) {
                object.mouse_event = $root.hbb.MouseEvent.toObject(message.mouse_event, options);
                if (options.oneofs)
                    object.union = "mouse_event";
            }
            if (message.audio_frame != null && message.hasOwnProperty("audio_frame")) {
                object.audio_frame = $root.hbb.AudioFrame.toObject(message.audio_frame, options);
                if (options.oneofs)
                    object.union = "audio_frame";
            }
            if (message.cursor_data != null && message.hasOwnProperty("cursor_data")) {
                object.cursor_data = $root.hbb.CursorData.toObject(message.cursor_data, options);
                if (options.oneofs)
                    object.union = "cursor_data";
            }
            if (message.cursor_position != null && message.hasOwnProperty("cursor_position")) {
                object.cursor_position = $root.hbb.CursorPosition.toObject(message.cursor_position, options);
                if (options.oneofs)
                    object.union = "cursor_position";
            }
            if (message.cursor_id != null && message.hasOwnProperty("cursor_id")) {
                if (typeof message.cursor_id === "number")
                    object.cursor_id = options.longs === String ? String(message.cursor_id) : message.cursor_id;
                else
                    object.cursor_id = options.longs === String ? $util.Long.prototype.toString.call(message.cursor_id) : options.longs === Number ? new $util.LongBits(message.cursor_id.low >>> 0, message.cursor_id.high >>> 0).toNumber(true) : message.cursor_id;
                if (options.oneofs)
                    object.union = "cursor_id";
            }
            if (message.key_event != null && message.hasOwnProperty("key_event")) {
                object.key_event = $root.hbb.KeyEvent.toObject(message.key_event, options);
                if (options.oneofs)
                    object.union = "key_event";
            }
            if (message.clipboard != null && message.hasOwnProperty("clipboard")) {
                object.clipboard = $root.hbb.Clipboard.toObject(message.clipboard, options);
                if (options.oneofs)
                    object.union = "clipboard";
            }
            if (message.file_action != null && message.hasOwnProperty("file_action")) {
                object.file_action = $root.hbb.FileAction.toObject(message.file_action, options);
                if (options.oneofs)
                    object.union = "file_action";
            }
            if (message.file_response != null && message.hasOwnProperty("file_response")) {
                object.file_response = $root.hbb.FileResponse.toObject(message.file_response, options);
                if (options.oneofs)
                    object.union = "file_response";
            }
            if (message.misc != null && message.hasOwnProperty("misc")) {
                object.misc = $root.hbb.Misc.toObject(message.misc, options);
                if (options.oneofs)
                    object.union = "misc";
            }
            if (message.cliprdr != null && message.hasOwnProperty("cliprdr")) {
                object.cliprdr = $root.hbb.Cliprdr.toObject(message.cliprdr, options);
                if (options.oneofs)
                    object.union = "cliprdr";
            }
            if (message.message_box != null && message.hasOwnProperty("message_box")) {
                object.message_box = $root.hbb.MessageBox.toObject(message.message_box, options);
                if (options.oneofs)
                    object.union = "message_box";
            }
            if (message.switch_sides_response != null && message.hasOwnProperty("switch_sides_response")) {
                object.switch_sides_response = $root.hbb.SwitchSidesResponse.toObject(message.switch_sides_response, options);
                if (options.oneofs)
                    object.union = "switch_sides_response";
            }
            if (message.voice_call_request != null && message.hasOwnProperty("voice_call_request")) {
                object.voice_call_request = $root.hbb.VoiceCallRequest.toObject(message.voice_call_request, options);
                if (options.oneofs)
                    object.union = "voice_call_request";
            }
            if (message.voice_call_response != null && message.hasOwnProperty("voice_call_response")) {
                object.voice_call_response = $root.hbb.VoiceCallResponse.toObject(message.voice_call_response, options);
                if (options.oneofs)
                    object.union = "voice_call_response";
            }
            if (message.peer_info != null && message.hasOwnProperty("peer_info")) {
                object.peer_info = $root.hbb.PeerInfo.toObject(message.peer_info, options);
                if (options.oneofs)
                    object.union = "peer_info";
            }
            if (message.pointer_device_event != null && message.hasOwnProperty("pointer_device_event")) {
                object.pointer_device_event = $root.hbb.PointerDeviceEvent.toObject(message.pointer_device_event, options);
                if (options.oneofs)
                    object.union = "pointer_device_event";
            }
            if (message.auth_2fa != null && message.hasOwnProperty("auth_2fa")) {
                object.auth_2fa = $root.hbb.Auth2FA.toObject(message.auth_2fa, options);
                if (options.oneofs)
                    object.union = "auth_2fa";
            }
            if (message.multi_clipboards != null && message.hasOwnProperty("multi_clipboards")) {
                object.multi_clipboards = $root.hbb.MultiClipboards.toObject(message.multi_clipboards, options);
                if (options.oneofs)
                    object.union = "multi_clipboards";
            }
            return object;
        };

        /**
         * Converts this Message to JSON.
         * @function toJSON
         * @memberof hbb.Message
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        Message.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for Message
         * @function getTypeUrl
         * @memberof hbb.Message
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        Message.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/hbb.Message";
        };

        return Message;
    })();

    return hbb;
})();

export { $root as default };
