// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
// versions:
//   protoc-gen-ts_proto  v2.6.1
//   protoc               v4.23.4
// source: src/timetable/proto/timetable.proto

/* eslint-disable */
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";

export const protobufPackage = "minotor.timetable";

export enum TransferType {
  RECOMMENDED_TRANSFER_POINT = 0,
  TIMED_TRANSFER = 1,
  REQUIRES_MINIMAL_TIME = 2,
  IN_SEAT_TRANSFER = 3,
  UNRECOGNIZED = -1,
}

export function transferTypeFromJSON(object: any): TransferType {
  switch (object) {
    case 0:
    case "RECOMMENDED_TRANSFER_POINT":
      return TransferType.RECOMMENDED_TRANSFER_POINT;
    case 1:
    case "TIMED_TRANSFER":
      return TransferType.TIMED_TRANSFER;
    case 2:
    case "REQUIRES_MINIMAL_TIME":
      return TransferType.REQUIRES_MINIMAL_TIME;
    case 3:
    case "IN_SEAT_TRANSFER":
      return TransferType.IN_SEAT_TRANSFER;
    case -1:
    case "UNRECOGNIZED":
    default:
      return TransferType.UNRECOGNIZED;
  }
}

export function transferTypeToJSON(object: TransferType): string {
  switch (object) {
    case TransferType.RECOMMENDED_TRANSFER_POINT:
      return "RECOMMENDED_TRANSFER_POINT";
    case TransferType.TIMED_TRANSFER:
      return "TIMED_TRANSFER";
    case TransferType.REQUIRES_MINIMAL_TIME:
      return "REQUIRES_MINIMAL_TIME";
    case TransferType.IN_SEAT_TRANSFER:
      return "IN_SEAT_TRANSFER";
    case TransferType.UNRECOGNIZED:
    default:
      return "UNRECOGNIZED";
  }
}

export enum RouteType {
  TRAM = 0,
  SUBWAY = 1,
  RAIL = 2,
  BUS = 3,
  FERRY = 4,
  CABLE_TRAM = 5,
  AERIAL_LIFT = 6,
  FUNICULAR = 7,
  TROLLEYBUS = 8,
  MONORAIL = 9,
  UNRECOGNIZED = -1,
}

export function routeTypeFromJSON(object: any): RouteType {
  switch (object) {
    case 0:
    case "TRAM":
      return RouteType.TRAM;
    case 1:
    case "SUBWAY":
      return RouteType.SUBWAY;
    case 2:
    case "RAIL":
      return RouteType.RAIL;
    case 3:
    case "BUS":
      return RouteType.BUS;
    case 4:
    case "FERRY":
      return RouteType.FERRY;
    case 5:
    case "CABLE_TRAM":
      return RouteType.CABLE_TRAM;
    case 6:
    case "AERIAL_LIFT":
      return RouteType.AERIAL_LIFT;
    case 7:
    case "FUNICULAR":
      return RouteType.FUNICULAR;
    case 8:
    case "TROLLEYBUS":
      return RouteType.TROLLEYBUS;
    case 9:
    case "MONORAIL":
      return RouteType.MONORAIL;
    case -1:
    case "UNRECOGNIZED":
    default:
      return RouteType.UNRECOGNIZED;
  }
}

export function routeTypeToJSON(object: RouteType): string {
  switch (object) {
    case RouteType.TRAM:
      return "TRAM";
    case RouteType.SUBWAY:
      return "SUBWAY";
    case RouteType.RAIL:
      return "RAIL";
    case RouteType.BUS:
      return "BUS";
    case RouteType.FERRY:
      return "FERRY";
    case RouteType.CABLE_TRAM:
      return "CABLE_TRAM";
    case RouteType.AERIAL_LIFT:
      return "AERIAL_LIFT";
    case RouteType.FUNICULAR:
      return "FUNICULAR";
    case RouteType.TROLLEYBUS:
      return "TROLLEYBUS";
    case RouteType.MONORAIL:
      return "MONORAIL";
    case RouteType.UNRECOGNIZED:
    default:
      return "UNRECOGNIZED";
  }
}

export interface Route {
  /**
   * Arrivals and departures encoded as a 32 bit uint array.
   * Format: [arrival1, departure1, arrival2, departure2, etc.]
   */
  stopTimes: Uint8Array;
  /**
   * PickUp and DropOff types represented as an 8 bit uint array.
   * Values:
   *   0: REGULAR
   *   1: NOT_AVAILABLE
   *   2: MUST_PHONE_AGENCY
   *   3: MUST_COORDINATE_WITH_DRIVER
   * Format: [pickupTypeStop1, dropOffTypeStop1, pickupTypeStop2, dropOffTypeStop2, etc.]
   */
  pickUpDropOffTypes: Uint8Array;
  /**
   * Stops encoded as a 32 bit uint array.
   * Format: [stop1, stop2, stop3, etc.]
   */
  stops: Uint8Array;
  serviceRouteId: string;
}

export interface RoutesAdjacency {
  routes: { [key: string]: Route };
}

export interface RoutesAdjacency_RoutesEntry {
  key: string;
  value: Route | undefined;
}

export interface Transfer {
  destination: number;
  type: TransferType;
  minTransferTime?: number | undefined;
}

export interface StopsAdjacency {
  stops: { [key: string]: StopsAdjacency_StopAdjacency };
}

export interface StopsAdjacency_StopAdjacency {
  transfers: Transfer[];
  routes: string[];
}

export interface StopsAdjacency_StopsEntry {
  key: string;
  value: StopsAdjacency_StopAdjacency | undefined;
}

export interface ServiceRoute {
  type: RouteType;
  name: string;
}

export interface ServiceRoutesMap {
  routes: { [key: string]: ServiceRoute };
}

export interface ServiceRoutesMap_RoutesEntry {
  key: string;
  value: ServiceRoute | undefined;
}

export interface Timetable {
  version: string;
  stopsAdjacency: StopsAdjacency | undefined;
  routesAdjacency: RoutesAdjacency | undefined;
  routes: ServiceRoutesMap | undefined;
}

function createBaseRoute(): Route {
  return {
    stopTimes: new Uint8Array(0),
    pickUpDropOffTypes: new Uint8Array(0),
    stops: new Uint8Array(0),
    serviceRouteId: "",
  };
}

export const Route: MessageFns<Route> = {
  encode(message: Route, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
    if (message.stopTimes.length !== 0) {
      writer.uint32(10).bytes(message.stopTimes);
    }
    if (message.pickUpDropOffTypes.length !== 0) {
      writer.uint32(18).bytes(message.pickUpDropOffTypes);
    }
    if (message.stops.length !== 0) {
      writer.uint32(26).bytes(message.stops);
    }
    if (message.serviceRouteId !== "") {
      writer.uint32(34).string(message.serviceRouteId);
    }
    return writer;
  },

  decode(input: BinaryReader | Uint8Array, length?: number): Route {
    const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
    let end = length === undefined ? reader.len : reader.pos + length;
    const message = createBaseRoute();
    while (reader.pos < end) {
      const tag = reader.uint32();
      switch (tag >>> 3) {
        case 1: {
          if (tag !== 10) {
            break;
          }

          message.stopTimes = reader.bytes();
          continue;
        }
        case 2: {
          if (tag !== 18) {
            break;
          }

          message.pickUpDropOffTypes = reader.bytes();
          continue;
        }
        case 3: {
          if (tag !== 26) {
            break;
          }

          message.stops = reader.bytes();
          continue;
        }
        case 4: {
          if (tag !== 34) {
            break;
          }

          message.serviceRouteId = reader.string();
          continue;
        }
      }
      if ((tag & 7) === 4 || tag === 0) {
        break;
      }
      reader.skip(tag & 7);
    }
    return message;
  },

  fromJSON(object: any): Route {
    return {
      stopTimes: isSet(object.stopTimes) ? bytesFromBase64(object.stopTimes) : new Uint8Array(0),
      pickUpDropOffTypes: isSet(object.pickUpDropOffTypes)
        ? bytesFromBase64(object.pickUpDropOffTypes)
        : new Uint8Array(0),
      stops: isSet(object.stops) ? bytesFromBase64(object.stops) : new Uint8Array(0),
      serviceRouteId: isSet(object.serviceRouteId) ? globalThis.String(object.serviceRouteId) : "",
    };
  },

  toJSON(message: Route): unknown {
    const obj: any = {};
    if (message.stopTimes.length !== 0) {
      obj.stopTimes = base64FromBytes(message.stopTimes);
    }
    if (message.pickUpDropOffTypes.length !== 0) {
      obj.pickUpDropOffTypes = base64FromBytes(message.pickUpDropOffTypes);
    }
    if (message.stops.length !== 0) {
      obj.stops = base64FromBytes(message.stops);
    }
    if (message.serviceRouteId !== "") {
      obj.serviceRouteId = message.serviceRouteId;
    }
    return obj;
  },

  create<I extends Exact<DeepPartial<Route>, I>>(base?: I): Route {
    return Route.fromPartial(base ?? ({} as any));
  },
  fromPartial<I extends Exact<DeepPartial<Route>, I>>(object: I): Route {
    const message = createBaseRoute();
    message.stopTimes = object.stopTimes ?? new Uint8Array(0);
    message.pickUpDropOffTypes = object.pickUpDropOffTypes ?? new Uint8Array(0);
    message.stops = object.stops ?? new Uint8Array(0);
    message.serviceRouteId = object.serviceRouteId ?? "";
    return message;
  },
};

function createBaseRoutesAdjacency(): RoutesAdjacency {
  return { routes: {} };
}

export const RoutesAdjacency: MessageFns<RoutesAdjacency> = {
  encode(message: RoutesAdjacency, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
    Object.entries(message.routes).forEach(([key, value]) => {
      RoutesAdjacency_RoutesEntry.encode({ key: key as any, value }, writer.uint32(10).fork()).join();
    });
    return writer;
  },

  decode(input: BinaryReader | Uint8Array, length?: number): RoutesAdjacency {
    const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
    let end = length === undefined ? reader.len : reader.pos + length;
    const message = createBaseRoutesAdjacency();
    while (reader.pos < end) {
      const tag = reader.uint32();
      switch (tag >>> 3) {
        case 1: {
          if (tag !== 10) {
            break;
          }

          const entry1 = RoutesAdjacency_RoutesEntry.decode(reader, reader.uint32());
          if (entry1.value !== undefined) {
            message.routes[entry1.key] = entry1.value;
          }
          continue;
        }
      }
      if ((tag & 7) === 4 || tag === 0) {
        break;
      }
      reader.skip(tag & 7);
    }
    return message;
  },

  fromJSON(object: any): RoutesAdjacency {
    return {
      routes: isObject(object.routes)
        ? Object.entries(object.routes).reduce<{ [key: string]: Route }>((acc, [key, value]) => {
          acc[key] = Route.fromJSON(value);
          return acc;
        }, {})
        : {},
    };
  },

  toJSON(message: RoutesAdjacency): unknown {
    const obj: any = {};
    if (message.routes) {
      const entries = Object.entries(message.routes);
      if (entries.length > 0) {
        obj.routes = {};
        entries.forEach(([k, v]) => {
          obj.routes[k] = Route.toJSON(v);
        });
      }
    }
    return obj;
  },

  create<I extends Exact<DeepPartial<RoutesAdjacency>, I>>(base?: I): RoutesAdjacency {
    return RoutesAdjacency.fromPartial(base ?? ({} as any));
  },
  fromPartial<I extends Exact<DeepPartial<RoutesAdjacency>, I>>(object: I): RoutesAdjacency {
    const message = createBaseRoutesAdjacency();
    message.routes = Object.entries(object.routes ?? {}).reduce<{ [key: string]: Route }>((acc, [key, value]) => {
      if (value !== undefined) {
        acc[key] = Route.fromPartial(value);
      }
      return acc;
    }, {});
    return message;
  },
};

function createBaseRoutesAdjacency_RoutesEntry(): RoutesAdjacency_RoutesEntry {
  return { key: "", value: undefined };
}

export const RoutesAdjacency_RoutesEntry: MessageFns<RoutesAdjacency_RoutesEntry> = {
  encode(message: RoutesAdjacency_RoutesEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
    if (message.key !== "") {
      writer.uint32(10).string(message.key);
    }
    if (message.value !== undefined) {
      Route.encode(message.value, writer.uint32(18).fork()).join();
    }
    return writer;
  },

  decode(input: BinaryReader | Uint8Array, length?: number): RoutesAdjacency_RoutesEntry {
    const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
    let end = length === undefined ? reader.len : reader.pos + length;
    const message = createBaseRoutesAdjacency_RoutesEntry();
    while (reader.pos < end) {
      const tag = reader.uint32();
      switch (tag >>> 3) {
        case 1: {
          if (tag !== 10) {
            break;
          }

          message.key = reader.string();
          continue;
        }
        case 2: {
          if (tag !== 18) {
            break;
          }

          message.value = Route.decode(reader, reader.uint32());
          continue;
        }
      }
      if ((tag & 7) === 4 || tag === 0) {
        break;
      }
      reader.skip(tag & 7);
    }
    return message;
  },

  fromJSON(object: any): RoutesAdjacency_RoutesEntry {
    return {
      key: isSet(object.key) ? globalThis.String(object.key) : "",
      value: isSet(object.value) ? Route.fromJSON(object.value) : undefined,
    };
  },

  toJSON(message: RoutesAdjacency_RoutesEntry): unknown {
    const obj: any = {};
    if (message.key !== "") {
      obj.key = message.key;
    }
    if (message.value !== undefined) {
      obj.value = Route.toJSON(message.value);
    }
    return obj;
  },

  create<I extends Exact<DeepPartial<RoutesAdjacency_RoutesEntry>, I>>(base?: I): RoutesAdjacency_RoutesEntry {
    return RoutesAdjacency_RoutesEntry.fromPartial(base ?? ({} as any));
  },
  fromPartial<I extends Exact<DeepPartial<RoutesAdjacency_RoutesEntry>, I>>(object: I): RoutesAdjacency_RoutesEntry {
    const message = createBaseRoutesAdjacency_RoutesEntry();
    message.key = object.key ?? "";
    message.value = (object.value !== undefined && object.value !== null) ? Route.fromPartial(object.value) : undefined;
    return message;
  },
};

function createBaseTransfer(): Transfer {
  return { destination: 0, type: 0, minTransferTime: undefined };
}

export const Transfer: MessageFns<Transfer> = {
  encode(message: Transfer, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
    if (message.destination !== 0) {
      writer.uint32(8).uint32(message.destination);
    }
    if (message.type !== 0) {
      writer.uint32(16).int32(message.type);
    }
    if (message.minTransferTime !== undefined) {
      writer.uint32(24).int32(message.minTransferTime);
    }
    return writer;
  },

  decode(input: BinaryReader | Uint8Array, length?: number): Transfer {
    const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
    let end = length === undefined ? reader.len : reader.pos + length;
    const message = createBaseTransfer();
    while (reader.pos < end) {
      const tag = reader.uint32();
      switch (tag >>> 3) {
        case 1: {
          if (tag !== 8) {
            break;
          }

          message.destination = reader.uint32();
          continue;
        }
        case 2: {
          if (tag !== 16) {
            break;
          }

          message.type = reader.int32() as any;
          continue;
        }
        case 3: {
          if (tag !== 24) {
            break;
          }

          message.minTransferTime = reader.int32();
          continue;
        }
      }
      if ((tag & 7) === 4 || tag === 0) {
        break;
      }
      reader.skip(tag & 7);
    }
    return message;
  },

  fromJSON(object: any): Transfer {
    return {
      destination: isSet(object.destination) ? globalThis.Number(object.destination) : 0,
      type: isSet(object.type) ? transferTypeFromJSON(object.type) : 0,
      minTransferTime: isSet(object.minTransferTime) ? globalThis.Number(object.minTransferTime) : undefined,
    };
  },

  toJSON(message: Transfer): unknown {
    const obj: any = {};
    if (message.destination !== 0) {
      obj.destination = Math.round(message.destination);
    }
    if (message.type !== 0) {
      obj.type = transferTypeToJSON(message.type);
    }
    if (message.minTransferTime !== undefined) {
      obj.minTransferTime = Math.round(message.minTransferTime);
    }
    return obj;
  },

  create<I extends Exact<DeepPartial<Transfer>, I>>(base?: I): Transfer {
    return Transfer.fromPartial(base ?? ({} as any));
  },
  fromPartial<I extends Exact<DeepPartial<Transfer>, I>>(object: I): Transfer {
    const message = createBaseTransfer();
    message.destination = object.destination ?? 0;
    message.type = object.type ?? 0;
    message.minTransferTime = object.minTransferTime ?? undefined;
    return message;
  },
};

function createBaseStopsAdjacency(): StopsAdjacency {
  return { stops: {} };
}

export const StopsAdjacency: MessageFns<StopsAdjacency> = {
  encode(message: StopsAdjacency, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
    Object.entries(message.stops).forEach(([key, value]) => {
      StopsAdjacency_StopsEntry.encode({ key: key as any, value }, writer.uint32(10).fork()).join();
    });
    return writer;
  },

  decode(input: BinaryReader | Uint8Array, length?: number): StopsAdjacency {
    const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
    let end = length === undefined ? reader.len : reader.pos + length;
    const message = createBaseStopsAdjacency();
    while (reader.pos < end) {
      const tag = reader.uint32();
      switch (tag >>> 3) {
        case 1: {
          if (tag !== 10) {
            break;
          }

          const entry1 = StopsAdjacency_StopsEntry.decode(reader, reader.uint32());
          if (entry1.value !== undefined) {
            message.stops[entry1.key] = entry1.value;
          }
          continue;
        }
      }
      if ((tag & 7) === 4 || tag === 0) {
        break;
      }
      reader.skip(tag & 7);
    }
    return message;
  },

  fromJSON(object: any): StopsAdjacency {
    return {
      stops: isObject(object.stops)
        ? Object.entries(object.stops).reduce<{ [key: string]: StopsAdjacency_StopAdjacency }>((acc, [key, value]) => {
          acc[key] = StopsAdjacency_StopAdjacency.fromJSON(value);
          return acc;
        }, {})
        : {},
    };
  },

  toJSON(message: StopsAdjacency): unknown {
    const obj: any = {};
    if (message.stops) {
      const entries = Object.entries(message.stops);
      if (entries.length > 0) {
        obj.stops = {};
        entries.forEach(([k, v]) => {
          obj.stops[k] = StopsAdjacency_StopAdjacency.toJSON(v);
        });
      }
    }
    return obj;
  },

  create<I extends Exact<DeepPartial<StopsAdjacency>, I>>(base?: I): StopsAdjacency {
    return StopsAdjacency.fromPartial(base ?? ({} as any));
  },
  fromPartial<I extends Exact<DeepPartial<StopsAdjacency>, I>>(object: I): StopsAdjacency {
    const message = createBaseStopsAdjacency();
    message.stops = Object.entries(object.stops ?? {}).reduce<{ [key: string]: StopsAdjacency_StopAdjacency }>(
      (acc, [key, value]) => {
        if (value !== undefined) {
          acc[key] = StopsAdjacency_StopAdjacency.fromPartial(value);
        }
        return acc;
      },
      {},
    );
    return message;
  },
};

function createBaseStopsAdjacency_StopAdjacency(): StopsAdjacency_StopAdjacency {
  return { transfers: [], routes: [] };
}

export const StopsAdjacency_StopAdjacency: MessageFns<StopsAdjacency_StopAdjacency> = {
  encode(message: StopsAdjacency_StopAdjacency, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
    for (const v of message.transfers) {
      Transfer.encode(v!, writer.uint32(10).fork()).join();
    }
    for (const v of message.routes) {
      writer.uint32(18).string(v!);
    }
    return writer;
  },

  decode(input: BinaryReader | Uint8Array, length?: number): StopsAdjacency_StopAdjacency {
    const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
    let end = length === undefined ? reader.len : reader.pos + length;
    const message = createBaseStopsAdjacency_StopAdjacency();
    while (reader.pos < end) {
      const tag = reader.uint32();
      switch (tag >>> 3) {
        case 1: {
          if (tag !== 10) {
            break;
          }

          message.transfers.push(Transfer.decode(reader, reader.uint32()));
          continue;
        }
        case 2: {
          if (tag !== 18) {
            break;
          }

          message.routes.push(reader.string());
          continue;
        }
      }
      if ((tag & 7) === 4 || tag === 0) {
        break;
      }
      reader.skip(tag & 7);
    }
    return message;
  },

  fromJSON(object: any): StopsAdjacency_StopAdjacency {
    return {
      transfers: globalThis.Array.isArray(object?.transfers)
        ? object.transfers.map((e: any) => Transfer.fromJSON(e))
        : [],
      routes: globalThis.Array.isArray(object?.routes) ? object.routes.map((e: any) => globalThis.String(e)) : [],
    };
  },

  toJSON(message: StopsAdjacency_StopAdjacency): unknown {
    const obj: any = {};
    if (message.transfers?.length) {
      obj.transfers = message.transfers.map((e) => Transfer.toJSON(e));
    }
    if (message.routes?.length) {
      obj.routes = message.routes;
    }
    return obj;
  },

  create<I extends Exact<DeepPartial<StopsAdjacency_StopAdjacency>, I>>(base?: I): StopsAdjacency_StopAdjacency {
    return StopsAdjacency_StopAdjacency.fromPartial(base ?? ({} as any));
  },
  fromPartial<I extends Exact<DeepPartial<StopsAdjacency_StopAdjacency>, I>>(object: I): StopsAdjacency_StopAdjacency {
    const message = createBaseStopsAdjacency_StopAdjacency();
    message.transfers = object.transfers?.map((e) => Transfer.fromPartial(e)) || [];
    message.routes = object.routes?.map((e) => e) || [];
    return message;
  },
};

function createBaseStopsAdjacency_StopsEntry(): StopsAdjacency_StopsEntry {
  return { key: "", value: undefined };
}

export const StopsAdjacency_StopsEntry: MessageFns<StopsAdjacency_StopsEntry> = {
  encode(message: StopsAdjacency_StopsEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
    if (message.key !== "") {
      writer.uint32(10).string(message.key);
    }
    if (message.value !== undefined) {
      StopsAdjacency_StopAdjacency.encode(message.value, writer.uint32(18).fork()).join();
    }
    return writer;
  },

  decode(input: BinaryReader | Uint8Array, length?: number): StopsAdjacency_StopsEntry {
    const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
    let end = length === undefined ? reader.len : reader.pos + length;
    const message = createBaseStopsAdjacency_StopsEntry();
    while (reader.pos < end) {
      const tag = reader.uint32();
      switch (tag >>> 3) {
        case 1: {
          if (tag !== 10) {
            break;
          }

          message.key = reader.string();
          continue;
        }
        case 2: {
          if (tag !== 18) {
            break;
          }

          message.value = StopsAdjacency_StopAdjacency.decode(reader, reader.uint32());
          continue;
        }
      }
      if ((tag & 7) === 4 || tag === 0) {
        break;
      }
      reader.skip(tag & 7);
    }
    return message;
  },

  fromJSON(object: any): StopsAdjacency_StopsEntry {
    return {
      key: isSet(object.key) ? globalThis.String(object.key) : "",
      value: isSet(object.value) ? StopsAdjacency_StopAdjacency.fromJSON(object.value) : undefined,
    };
  },

  toJSON(message: StopsAdjacency_StopsEntry): unknown {
    const obj: any = {};
    if (message.key !== "") {
      obj.key = message.key;
    }
    if (message.value !== undefined) {
      obj.value = StopsAdjacency_StopAdjacency.toJSON(message.value);
    }
    return obj;
  },

  create<I extends Exact<DeepPartial<StopsAdjacency_StopsEntry>, I>>(base?: I): StopsAdjacency_StopsEntry {
    return StopsAdjacency_StopsEntry.fromPartial(base ?? ({} as any));
  },
  fromPartial<I extends Exact<DeepPartial<StopsAdjacency_StopsEntry>, I>>(object: I): StopsAdjacency_StopsEntry {
    const message = createBaseStopsAdjacency_StopsEntry();
    message.key = object.key ?? "";
    message.value = (object.value !== undefined && object.value !== null)
      ? StopsAdjacency_StopAdjacency.fromPartial(object.value)
      : undefined;
    return message;
  },
};

function createBaseServiceRoute(): ServiceRoute {
  return { type: 0, name: "" };
}

export const ServiceRoute: MessageFns<ServiceRoute> = {
  encode(message: ServiceRoute, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
    if (message.type !== 0) {
      writer.uint32(8).int32(message.type);
    }
    if (message.name !== "") {
      writer.uint32(18).string(message.name);
    }
    return writer;
  },

  decode(input: BinaryReader | Uint8Array, length?: number): ServiceRoute {
    const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
    let end = length === undefined ? reader.len : reader.pos + length;
    const message = createBaseServiceRoute();
    while (reader.pos < end) {
      const tag = reader.uint32();
      switch (tag >>> 3) {
        case 1: {
          if (tag !== 8) {
            break;
          }

          message.type = reader.int32() as any;
          continue;
        }
        case 2: {
          if (tag !== 18) {
            break;
          }

          message.name = reader.string();
          continue;
        }
      }
      if ((tag & 7) === 4 || tag === 0) {
        break;
      }
      reader.skip(tag & 7);
    }
    return message;
  },

  fromJSON(object: any): ServiceRoute {
    return {
      type: isSet(object.type) ? routeTypeFromJSON(object.type) : 0,
      name: isSet(object.name) ? globalThis.String(object.name) : "",
    };
  },

  toJSON(message: ServiceRoute): unknown {
    const obj: any = {};
    if (message.type !== 0) {
      obj.type = routeTypeToJSON(message.type);
    }
    if (message.name !== "") {
      obj.name = message.name;
    }
    return obj;
  },

  create<I extends Exact<DeepPartial<ServiceRoute>, I>>(base?: I): ServiceRoute {
    return ServiceRoute.fromPartial(base ?? ({} as any));
  },
  fromPartial<I extends Exact<DeepPartial<ServiceRoute>, I>>(object: I): ServiceRoute {
    const message = createBaseServiceRoute();
    message.type = object.type ?? 0;
    message.name = object.name ?? "";
    return message;
  },
};

function createBaseServiceRoutesMap(): ServiceRoutesMap {
  return { routes: {} };
}

export const ServiceRoutesMap: MessageFns<ServiceRoutesMap> = {
  encode(message: ServiceRoutesMap, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
    Object.entries(message.routes).forEach(([key, value]) => {
      ServiceRoutesMap_RoutesEntry.encode({ key: key as any, value }, writer.uint32(10).fork()).join();
    });
    return writer;
  },

  decode(input: BinaryReader | Uint8Array, length?: number): ServiceRoutesMap {
    const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
    let end = length === undefined ? reader.len : reader.pos + length;
    const message = createBaseServiceRoutesMap();
    while (reader.pos < end) {
      const tag = reader.uint32();
      switch (tag >>> 3) {
        case 1: {
          if (tag !== 10) {
            break;
          }

          const entry1 = ServiceRoutesMap_RoutesEntry.decode(reader, reader.uint32());
          if (entry1.value !== undefined) {
            message.routes[entry1.key] = entry1.value;
          }
          continue;
        }
      }
      if ((tag & 7) === 4 || tag === 0) {
        break;
      }
      reader.skip(tag & 7);
    }
    return message;
  },

  fromJSON(object: any): ServiceRoutesMap {
    return {
      routes: isObject(object.routes)
        ? Object.entries(object.routes).reduce<{ [key: string]: ServiceRoute }>((acc, [key, value]) => {
          acc[key] = ServiceRoute.fromJSON(value);
          return acc;
        }, {})
        : {},
    };
  },

  toJSON(message: ServiceRoutesMap): unknown {
    const obj: any = {};
    if (message.routes) {
      const entries = Object.entries(message.routes);
      if (entries.length > 0) {
        obj.routes = {};
        entries.forEach(([k, v]) => {
          obj.routes[k] = ServiceRoute.toJSON(v);
        });
      }
    }
    return obj;
  },

  create<I extends Exact<DeepPartial<ServiceRoutesMap>, I>>(base?: I): ServiceRoutesMap {
    return ServiceRoutesMap.fromPartial(base ?? ({} as any));
  },
  fromPartial<I extends Exact<DeepPartial<ServiceRoutesMap>, I>>(object: I): ServiceRoutesMap {
    const message = createBaseServiceRoutesMap();
    message.routes = Object.entries(object.routes ?? {}).reduce<{ [key: string]: ServiceRoute }>(
      (acc, [key, value]) => {
        if (value !== undefined) {
          acc[key] = ServiceRoute.fromPartial(value);
        }
        return acc;
      },
      {},
    );
    return message;
  },
};

function createBaseServiceRoutesMap_RoutesEntry(): ServiceRoutesMap_RoutesEntry {
  return { key: "", value: undefined };
}

export const ServiceRoutesMap_RoutesEntry: MessageFns<ServiceRoutesMap_RoutesEntry> = {
  encode(message: ServiceRoutesMap_RoutesEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
    if (message.key !== "") {
      writer.uint32(10).string(message.key);
    }
    if (message.value !== undefined) {
      ServiceRoute.encode(message.value, writer.uint32(18).fork()).join();
    }
    return writer;
  },

  decode(input: BinaryReader | Uint8Array, length?: number): ServiceRoutesMap_RoutesEntry {
    const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
    let end = length === undefined ? reader.len : reader.pos + length;
    const message = createBaseServiceRoutesMap_RoutesEntry();
    while (reader.pos < end) {
      const tag = reader.uint32();
      switch (tag >>> 3) {
        case 1: {
          if (tag !== 10) {
            break;
          }

          message.key = reader.string();
          continue;
        }
        case 2: {
          if (tag !== 18) {
            break;
          }

          message.value = ServiceRoute.decode(reader, reader.uint32());
          continue;
        }
      }
      if ((tag & 7) === 4 || tag === 0) {
        break;
      }
      reader.skip(tag & 7);
    }
    return message;
  },

  fromJSON(object: any): ServiceRoutesMap_RoutesEntry {
    return {
      key: isSet(object.key) ? globalThis.String(object.key) : "",
      value: isSet(object.value) ? ServiceRoute.fromJSON(object.value) : undefined,
    };
  },

  toJSON(message: ServiceRoutesMap_RoutesEntry): unknown {
    const obj: any = {};
    if (message.key !== "") {
      obj.key = message.key;
    }
    if (message.value !== undefined) {
      obj.value = ServiceRoute.toJSON(message.value);
    }
    return obj;
  },

  create<I extends Exact<DeepPartial<ServiceRoutesMap_RoutesEntry>, I>>(base?: I): ServiceRoutesMap_RoutesEntry {
    return ServiceRoutesMap_RoutesEntry.fromPartial(base ?? ({} as any));
  },
  fromPartial<I extends Exact<DeepPartial<ServiceRoutesMap_RoutesEntry>, I>>(object: I): ServiceRoutesMap_RoutesEntry {
    const message = createBaseServiceRoutesMap_RoutesEntry();
    message.key = object.key ?? "";
    message.value = (object.value !== undefined && object.value !== null)
      ? ServiceRoute.fromPartial(object.value)
      : undefined;
    return message;
  },
};

function createBaseTimetable(): Timetable {
  return { version: "", stopsAdjacency: undefined, routesAdjacency: undefined, routes: undefined };
}

export const Timetable: MessageFns<Timetable> = {
  encode(message: Timetable, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
    if (message.version !== "") {
      writer.uint32(10).string(message.version);
    }
    if (message.stopsAdjacency !== undefined) {
      StopsAdjacency.encode(message.stopsAdjacency, writer.uint32(18).fork()).join();
    }
    if (message.routesAdjacency !== undefined) {
      RoutesAdjacency.encode(message.routesAdjacency, writer.uint32(26).fork()).join();
    }
    if (message.routes !== undefined) {
      ServiceRoutesMap.encode(message.routes, writer.uint32(34).fork()).join();
    }
    return writer;
  },

  decode(input: BinaryReader | Uint8Array, length?: number): Timetable {
    const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
    let end = length === undefined ? reader.len : reader.pos + length;
    const message = createBaseTimetable();
    while (reader.pos < end) {
      const tag = reader.uint32();
      switch (tag >>> 3) {
        case 1: {
          if (tag !== 10) {
            break;
          }

          message.version = reader.string();
          continue;
        }
        case 2: {
          if (tag !== 18) {
            break;
          }

          message.stopsAdjacency = StopsAdjacency.decode(reader, reader.uint32());
          continue;
        }
        case 3: {
          if (tag !== 26) {
            break;
          }

          message.routesAdjacency = RoutesAdjacency.decode(reader, reader.uint32());
          continue;
        }
        case 4: {
          if (tag !== 34) {
            break;
          }

          message.routes = ServiceRoutesMap.decode(reader, reader.uint32());
          continue;
        }
      }
      if ((tag & 7) === 4 || tag === 0) {
        break;
      }
      reader.skip(tag & 7);
    }
    return message;
  },

  fromJSON(object: any): Timetable {
    return {
      version: isSet(object.version) ? globalThis.String(object.version) : "",
      stopsAdjacency: isSet(object.stopsAdjacency) ? StopsAdjacency.fromJSON(object.stopsAdjacency) : undefined,
      routesAdjacency: isSet(object.routesAdjacency) ? RoutesAdjacency.fromJSON(object.routesAdjacency) : undefined,
      routes: isSet(object.routes) ? ServiceRoutesMap.fromJSON(object.routes) : undefined,
    };
  },

  toJSON(message: Timetable): unknown {
    const obj: any = {};
    if (message.version !== "") {
      obj.version = message.version;
    }
    if (message.stopsAdjacency !== undefined) {
      obj.stopsAdjacency = StopsAdjacency.toJSON(message.stopsAdjacency);
    }
    if (message.routesAdjacency !== undefined) {
      obj.routesAdjacency = RoutesAdjacency.toJSON(message.routesAdjacency);
    }
    if (message.routes !== undefined) {
      obj.routes = ServiceRoutesMap.toJSON(message.routes);
    }
    return obj;
  },

  create<I extends Exact<DeepPartial<Timetable>, I>>(base?: I): Timetable {
    return Timetable.fromPartial(base ?? ({} as any));
  },
  fromPartial<I extends Exact<DeepPartial<Timetable>, I>>(object: I): Timetable {
    const message = createBaseTimetable();
    message.version = object.version ?? "";
    message.stopsAdjacency = (object.stopsAdjacency !== undefined && object.stopsAdjacency !== null)
      ? StopsAdjacency.fromPartial(object.stopsAdjacency)
      : undefined;
    message.routesAdjacency = (object.routesAdjacency !== undefined && object.routesAdjacency !== null)
      ? RoutesAdjacency.fromPartial(object.routesAdjacency)
      : undefined;
    message.routes = (object.routes !== undefined && object.routes !== null)
      ? ServiceRoutesMap.fromPartial(object.routes)
      : undefined;
    return message;
  },
};

function bytesFromBase64(b64: string): Uint8Array {
  if ((globalThis as any).Buffer) {
    return Uint8Array.from(globalThis.Buffer.from(b64, "base64"));
  } else {
    const bin = globalThis.atob(b64);
    const arr = new Uint8Array(bin.length);
    for (let i = 0; i < bin.length; ++i) {
      arr[i] = bin.charCodeAt(i);
    }
    return arr;
  }
}

function base64FromBytes(arr: Uint8Array): string {
  if ((globalThis as any).Buffer) {
    return globalThis.Buffer.from(arr).toString("base64");
  } else {
    const bin: string[] = [];
    arr.forEach((byte) => {
      bin.push(globalThis.String.fromCharCode(byte));
    });
    return globalThis.btoa(bin.join(""));
  }
}

type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;

export type DeepPartial<T> = T extends Builtin ? T
  : T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial<U>>
  : T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>>
  : T extends {} ? { [K in keyof T]?: DeepPartial<T[K]> }
  : Partial<T>;

type KeysOfUnion<T> = T extends T ? keyof T : never;
export type Exact<P, I extends P> = P extends Builtin ? P
  : P & { [K in keyof P]: Exact<P[K], I[K]> } & { [K in Exclude<keyof I, KeysOfUnion<P>>]: never };

function isObject(value: any): boolean {
  return typeof value === "object" && value !== null;
}

function isSet(value: any): boolean {
  return value !== null && value !== undefined;
}

export interface MessageFns<T> {
  encode(message: T, writer?: BinaryWriter): BinaryWriter;
  decode(input: BinaryReader | Uint8Array, length?: number): T;
  fromJSON(object: any): T;
  toJSON(message: T): unknown;
  create<I extends Exact<DeepPartial<T>, I>>(base?: I): T;
  fromPartial<I extends Exact<DeepPartial<T>, I>>(object: I): T;
}
