# Copyright: Ankitects Pty Ltd and contributors
# License: GNU AGPL, version 3 or later; https://www.gnu.org/licenses/agpl.html

from __future__ import annotations

"""
THIS FILE IS AUTOMATICALLY GENERATED - DO NOT EDIT.

Please do not access methods on the backend directly - they may be changed
or removed at any time. Instead, please use the methods on the collection
instead. Eg, don't use col.backend.all_deck_config(), instead use
col.decks.all_config()
"""

from typing import *

import anki
import anki.ankiweb_pb2
import anki.backend_pb2
import anki.card_rendering_pb2
import anki.cards_pb2
import anki.collection_pb2
import anki.config_pb2
import anki.deck_config_pb2
import anki.decks_pb2
import anki.i18n_pb2
import anki.image_occlusion_pb2
import anki.import_export_pb2
import anki.links_pb2
import anki.media_pb2
import anki.notes_pb2
import anki.notetypes_pb2
import anki.scheduler_pb2
import anki.search_pb2
import anki.stats_pb2
import anki.sync_pb2
import anki.tags_pb2
import anki.ankihub_pb2

class RustBackendGenerated:
    def _run_command(self, service: int, method: int, input: Any) -> bytes:
        raise Exception("not implemented")

    def sync_media_raw(self, message: bytes) -> bytes:
        return self._run_command(1, 0, message)

    def sync_media(self, message: anki.sync_pb2.SyncAuth) -> anki.generic_pb2.Empty:
        
        raw_bytes = self._run_command(1, 0, message.SerializeToString())
        output = anki.generic_pb2.Empty()
        output.ParseFromString(raw_bytes)
        return output

    def abort_media_sync_raw(self, message: bytes) -> bytes:
        return self._run_command(1, 1, message)

    def abort_media_sync(self) -> anki.generic_pb2.Empty:
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(1, 1, message.SerializeToString())
        output = anki.generic_pb2.Empty()
        output.ParseFromString(raw_bytes)
        return output

    def media_sync_status_raw(self, message: bytes) -> bytes:
        """Can be used by the frontend to detect an active sync. If the sync aborted
 with an error, the next call to this method will return the error."""
        return self._run_command(1, 2, message)

    def media_sync_status(self) -> anki.sync_pb2.MediaSyncStatusResponse:
        """Can be used by the frontend to detect an active sync. If the sync aborted
 with an error, the next call to this method will return the error."""
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(1, 2, message.SerializeToString())
        output = anki.sync_pb2.MediaSyncStatusResponse()
        output.ParseFromString(raw_bytes)
        return output

    def sync_login_raw(self, message: bytes) -> bytes:
        return self._run_command(1, 3, message)

    def sync_login(self, message: anki.sync_pb2.SyncLoginRequest) -> anki.sync_pb2.SyncAuth:
        
        raw_bytes = self._run_command(1, 3, message.SerializeToString())
        output = anki.sync_pb2.SyncAuth()
        output.ParseFromString(raw_bytes)
        return output

    def sync_status_raw(self, message: bytes) -> bytes:
        return self._run_command(1, 4, message)

    def sync_status(self, message: anki.sync_pb2.SyncAuth) -> anki.sync_pb2.SyncStatusResponse:
        
        raw_bytes = self._run_command(1, 4, message.SerializeToString())
        output = anki.sync_pb2.SyncStatusResponse()
        output.ParseFromString(raw_bytes)
        return output

    def sync_collection_raw(self, message: bytes) -> bytes:
        return self._run_command(1, 5, message)

    def sync_collection(self, *, auth: anki.sync_pb2.SyncAuth, sync_media: bool) -> anki.sync_pb2.SyncCollectionResponse:
        message = anki.sync_pb2.SyncCollectionRequest(auth=auth, sync_media=sync_media)
        raw_bytes = self._run_command(1, 5, message.SerializeToString())
        output = anki.sync_pb2.SyncCollectionResponse()
        output.ParseFromString(raw_bytes)
        return output

    def full_upload_or_download_raw(self, message: bytes) -> bytes:
        return self._run_command(1, 6, message)

    def full_upload_or_download(self, message: anki.sync_pb2.FullUploadOrDownloadRequest) -> anki.generic_pb2.Empty:
        
        raw_bytes = self._run_command(1, 6, message.SerializeToString())
        output = anki.generic_pb2.Empty()
        output.ParseFromString(raw_bytes)
        return output

    def abort_sync_raw(self, message: bytes) -> bytes:
        return self._run_command(1, 7, message)

    def abort_sync(self) -> anki.generic_pb2.Empty:
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(1, 7, message.SerializeToString())
        output = anki.generic_pb2.Empty()
        output.ParseFromString(raw_bytes)
        return output

    def set_custom_certificate_raw(self, message: bytes) -> bytes:
        return self._run_command(1, 8, message)

    def set_custom_certificate(self, val: str) -> bool:
        message = anki.generic_pb2.String(val=val)
        raw_bytes = self._run_command(1, 8, message.SerializeToString())
        output = anki.generic_pb2.Bool()
        output.ParseFromString(raw_bytes)
        return output.val

    def open_collection_raw(self, message: bytes) -> bytes:
        return self._run_command(3, 0, message)

    def open_collection(self, *, collection_path: str, media_folder_path: str, media_db_path: str) -> anki.generic_pb2.Empty:
        message = anki.collection_pb2.OpenCollectionRequest(collection_path=collection_path, media_folder_path=media_folder_path, media_db_path=media_db_path)
        raw_bytes = self._run_command(3, 0, message.SerializeToString())
        output = anki.generic_pb2.Empty()
        output.ParseFromString(raw_bytes)
        return output

    def close_collection_raw(self, message: bytes) -> bytes:
        return self._run_command(3, 1, message)

    def close_collection(self, downgrade_to_schema11: bool) -> anki.generic_pb2.Empty:
        message = anki.collection_pb2.CloseCollectionRequest(downgrade_to_schema11=downgrade_to_schema11)
        raw_bytes = self._run_command(3, 1, message.SerializeToString())
        output = anki.generic_pb2.Empty()
        output.ParseFromString(raw_bytes)
        return output

    def create_backup_raw(self, message: bytes) -> bytes:
        """Create a no-media backup. Caller must ensure there is no active
 transaction. Unlike a collection export, does not require reopening the DB,
 as there is no downgrade step.
 Returns false if it's not time to make a backup yet."""
        return self._run_command(3, 2, message)

    def create_backup(self, *, backup_folder: str, force: bool, wait_for_completion: bool) -> bool:
        """Create a no-media backup. Caller must ensure there is no active
 transaction. Unlike a collection export, does not require reopening the DB,
 as there is no downgrade step.
 Returns false if it's not time to make a backup yet."""
        message = anki.collection_pb2.CreateBackupRequest(backup_folder=backup_folder, force=force, wait_for_completion=wait_for_completion)
        raw_bytes = self._run_command(3, 2, message.SerializeToString())
        output = anki.generic_pb2.Bool()
        output.ParseFromString(raw_bytes)
        return output.val

    def await_backup_completion_raw(self, message: bytes) -> bytes:
        """If a backup is running, wait for it to complete. Will return an error
 if the backup encountered an error."""
        return self._run_command(3, 3, message)

    def await_backup_completion(self) -> anki.generic_pb2.Empty:
        """If a backup is running, wait for it to complete. Will return an error
 if the backup encountered an error."""
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(3, 3, message.SerializeToString())
        output = anki.generic_pb2.Empty()
        output.ParseFromString(raw_bytes)
        return output

    def latest_progress_raw(self, message: bytes) -> bytes:
        return self._run_command(3, 4, message)

    def latest_progress(self) -> anki.collection_pb2.Progress:
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(3, 4, message.SerializeToString())
        output = anki.collection_pb2.Progress()
        output.ParseFromString(raw_bytes)
        return output

    def set_wants_abort_raw(self, message: bytes) -> bytes:
        return self._run_command(3, 5, message)

    def set_wants_abort(self) -> anki.generic_pb2.Empty:
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(3, 5, message.SerializeToString())
        output = anki.generic_pb2.Empty()
        output.ParseFromString(raw_bytes)
        return output

    def check_database_raw(self, message: bytes) -> bytes:
        return self._run_command(3, 6, message)

    def check_database(self) -> Sequence[str]:
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(3, 6, message.SerializeToString())
        output = anki.collection_pb2.CheckDatabaseResponse()
        output.ParseFromString(raw_bytes)
        return output.problems

    def get_undo_status_raw(self, message: bytes) -> bytes:
        return self._run_command(3, 7, message)

    def get_undo_status(self) -> anki.collection_pb2.UndoStatus:
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(3, 7, message.SerializeToString())
        output = anki.collection_pb2.UndoStatus()
        output.ParseFromString(raw_bytes)
        return output

    def undo_raw(self, message: bytes) -> bytes:
        return self._run_command(3, 8, message)

    def undo(self) -> anki.collection_pb2.OpChangesAfterUndo:
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(3, 8, message.SerializeToString())
        output = anki.collection_pb2.OpChangesAfterUndo()
        output.ParseFromString(raw_bytes)
        return output

    def redo_raw(self, message: bytes) -> bytes:
        return self._run_command(3, 9, message)

    def redo(self) -> anki.collection_pb2.OpChangesAfterUndo:
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(3, 9, message.SerializeToString())
        output = anki.collection_pb2.OpChangesAfterUndo()
        output.ParseFromString(raw_bytes)
        return output

    def add_custom_undo_entry_raw(self, message: bytes) -> bytes:
        return self._run_command(3, 10, message)

    def add_custom_undo_entry(self, val: str) -> int:
        message = anki.generic_pb2.String(val=val)
        raw_bytes = self._run_command(3, 10, message.SerializeToString())
        output = anki.generic_pb2.UInt32()
        output.ParseFromString(raw_bytes)
        return output.val

    def merge_undo_entries_raw(self, message: bytes) -> bytes:
        return self._run_command(3, 11, message)

    def merge_undo_entries(self, val: int) -> anki.collection_pb2.OpChanges:
        message = anki.generic_pb2.UInt32(val=val)
        raw_bytes = self._run_command(3, 11, message.SerializeToString())
        output = anki.collection_pb2.OpChanges()
        output.ParseFromString(raw_bytes)
        return output

    def set_load_balancer_enabled_raw(self, message: bytes) -> bytes:
        return self._run_command(3, 14, message)

    def set_load_balancer_enabled(self, val: bool) -> anki.collection_pb2.OpChanges:
        message = anki.generic_pb2.Bool(val=val)
        raw_bytes = self._run_command(3, 14, message.SerializeToString())
        output = anki.collection_pb2.OpChanges()
        output.ParseFromString(raw_bytes)
        return output

    def get_card_raw(self, message: bytes) -> bytes:
        return self._run_command(5, 0, message)

    def get_card(self, cid: int) -> anki.cards_pb2.Card:
        message = anki.cards_pb2.CardId(cid=cid)
        raw_bytes = self._run_command(5, 0, message.SerializeToString())
        output = anki.cards_pb2.Card()
        output.ParseFromString(raw_bytes)
        return output

    def update_cards_raw(self, message: bytes) -> bytes:
        return self._run_command(5, 1, message)

    def update_cards(self, *, cards: Iterable[anki.cards_pb2.Card], skip_undo_entry: bool) -> anki.collection_pb2.OpChanges:
        message = anki.cards_pb2.UpdateCardsRequest(cards=cards, skip_undo_entry=skip_undo_entry)
        raw_bytes = self._run_command(5, 1, message.SerializeToString())
        output = anki.collection_pb2.OpChanges()
        output.ParseFromString(raw_bytes)
        return output

    def remove_cards_raw(self, message: bytes) -> bytes:
        return self._run_command(5, 2, message)

    def remove_cards(self, card_ids: Iterable[int]) -> anki.collection_pb2.OpChangesWithCount:
        message = anki.cards_pb2.RemoveCardsRequest(card_ids=card_ids)
        raw_bytes = self._run_command(5, 2, message.SerializeToString())
        output = anki.collection_pb2.OpChangesWithCount()
        output.ParseFromString(raw_bytes)
        return output

    def set_deck_raw(self, message: bytes) -> bytes:
        return self._run_command(5, 3, message)

    def set_deck(self, *, card_ids: Iterable[int], deck_id: int) -> anki.collection_pb2.OpChangesWithCount:
        message = anki.cards_pb2.SetDeckRequest(card_ids=card_ids, deck_id=deck_id)
        raw_bytes = self._run_command(5, 3, message.SerializeToString())
        output = anki.collection_pb2.OpChangesWithCount()
        output.ParseFromString(raw_bytes)
        return output

    def set_flag_raw(self, message: bytes) -> bytes:
        return self._run_command(5, 4, message)

    def set_flag(self, *, card_ids: Iterable[int], flag: int) -> anki.collection_pb2.OpChangesWithCount:
        message = anki.cards_pb2.SetFlagRequest(card_ids=card_ids, flag=flag)
        raw_bytes = self._run_command(5, 4, message.SerializeToString())
        output = anki.collection_pb2.OpChangesWithCount()
        output.ParseFromString(raw_bytes)
        return output

    def new_deck_raw(self, message: bytes) -> bytes:
        return self._run_command(7, 0, message)

    def new_deck(self) -> anki.decks_pb2.Deck:
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(7, 0, message.SerializeToString())
        output = anki.decks_pb2.Deck()
        output.ParseFromString(raw_bytes)
        return output

    def add_deck_raw(self, message: bytes) -> bytes:
        return self._run_command(7, 1, message)

    def add_deck(self, message: anki.decks_pb2.Deck) -> anki.collection_pb2.OpChangesWithId:
        
        raw_bytes = self._run_command(7, 1, message.SerializeToString())
        output = anki.collection_pb2.OpChangesWithId()
        output.ParseFromString(raw_bytes)
        return output

    def add_deck_legacy_raw(self, message: bytes) -> bytes:
        return self._run_command(7, 2, message)

    def add_deck_legacy(self, json: bytes) -> anki.collection_pb2.OpChangesWithId:
        message = anki.generic_pb2.Json(json=json)
        raw_bytes = self._run_command(7, 2, message.SerializeToString())
        output = anki.collection_pb2.OpChangesWithId()
        output.ParseFromString(raw_bytes)
        return output

    def add_or_update_deck_legacy_raw(self, message: bytes) -> bytes:
        return self._run_command(7, 3, message)

    def add_or_update_deck_legacy(self, *, deck: bytes, preserve_usn_and_mtime: bool) -> int:
        message = anki.decks_pb2.AddOrUpdateDeckLegacyRequest(deck=deck, preserve_usn_and_mtime=preserve_usn_and_mtime)
        raw_bytes = self._run_command(7, 3, message.SerializeToString())
        output = anki.decks_pb2.DeckId()
        output.ParseFromString(raw_bytes)
        return output.did

    def deck_tree_raw(self, message: bytes) -> bytes:
        return self._run_command(7, 4, message)

    def deck_tree(self, now: int) -> anki.decks_pb2.DeckTreeNode:
        message = anki.decks_pb2.DeckTreeRequest(now=now)
        raw_bytes = self._run_command(7, 4, message.SerializeToString())
        output = anki.decks_pb2.DeckTreeNode()
        output.ParseFromString(raw_bytes)
        return output

    def deck_tree_legacy_raw(self, message: bytes) -> bytes:
        return self._run_command(7, 5, message)

    def deck_tree_legacy(self) -> bytes:
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(7, 5, message.SerializeToString())
        output = anki.generic_pb2.Json()
        output.ParseFromString(raw_bytes)
        return output.json

    def get_all_decks_legacy_raw(self, message: bytes) -> bytes:
        return self._run_command(7, 6, message)

    def get_all_decks_legacy(self) -> bytes:
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(7, 6, message.SerializeToString())
        output = anki.generic_pb2.Json()
        output.ParseFromString(raw_bytes)
        return output.json

    def get_deck_id_by_name_raw(self, message: bytes) -> bytes:
        return self._run_command(7, 7, message)

    def get_deck_id_by_name(self, val: str) -> int:
        message = anki.generic_pb2.String(val=val)
        raw_bytes = self._run_command(7, 7, message.SerializeToString())
        output = anki.decks_pb2.DeckId()
        output.ParseFromString(raw_bytes)
        return output.did

    def get_deck_raw(self, message: bytes) -> bytes:
        return self._run_command(7, 8, message)

    def get_deck(self, did: int) -> anki.decks_pb2.Deck:
        message = anki.decks_pb2.DeckId(did=did)
        raw_bytes = self._run_command(7, 8, message.SerializeToString())
        output = anki.decks_pb2.Deck()
        output.ParseFromString(raw_bytes)
        return output

    def update_deck_raw(self, message: bytes) -> bytes:
        return self._run_command(7, 9, message)

    def update_deck(self, message: anki.decks_pb2.Deck) -> anki.collection_pb2.OpChanges:
        
        raw_bytes = self._run_command(7, 9, message.SerializeToString())
        output = anki.collection_pb2.OpChanges()
        output.ParseFromString(raw_bytes)
        return output

    def update_deck_legacy_raw(self, message: bytes) -> bytes:
        return self._run_command(7, 10, message)

    def update_deck_legacy(self, json: bytes) -> anki.collection_pb2.OpChanges:
        message = anki.generic_pb2.Json(json=json)
        raw_bytes = self._run_command(7, 10, message.SerializeToString())
        output = anki.collection_pb2.OpChanges()
        output.ParseFromString(raw_bytes)
        return output

    def set_deck_collapsed_raw(self, message: bytes) -> bytes:
        return self._run_command(7, 11, message)

    def set_deck_collapsed(self, *, deck_id: int, collapsed: bool, scope: anki.decks_pb2.SetDeckCollapsedRequest.Scope.V) -> anki.collection_pb2.OpChanges:
        message = anki.decks_pb2.SetDeckCollapsedRequest(deck_id=deck_id, collapsed=collapsed, scope=scope)
        raw_bytes = self._run_command(7, 11, message.SerializeToString())
        output = anki.collection_pb2.OpChanges()
        output.ParseFromString(raw_bytes)
        return output

    def get_deck_legacy_raw(self, message: bytes) -> bytes:
        return self._run_command(7, 12, message)

    def get_deck_legacy(self, did: int) -> bytes:
        message = anki.decks_pb2.DeckId(did=did)
        raw_bytes = self._run_command(7, 12, message.SerializeToString())
        output = anki.generic_pb2.Json()
        output.ParseFromString(raw_bytes)
        return output.json

    def get_deck_names_raw(self, message: bytes) -> bytes:
        return self._run_command(7, 13, message)

    def get_deck_names(self, *, skip_empty_default: bool, include_filtered: bool) -> Sequence[anki.decks_pb2.DeckNameId]:
        message = anki.decks_pb2.GetDeckNamesRequest(skip_empty_default=skip_empty_default, include_filtered=include_filtered)
        raw_bytes = self._run_command(7, 13, message.SerializeToString())
        output = anki.decks_pb2.DeckNames()
        output.ParseFromString(raw_bytes)
        return output.entries

    def get_deck_and_child_names_raw(self, message: bytes) -> bytes:
        return self._run_command(7, 14, message)

    def get_deck_and_child_names(self, did: int) -> Sequence[anki.decks_pb2.DeckNameId]:
        message = anki.decks_pb2.DeckId(did=did)
        raw_bytes = self._run_command(7, 14, message.SerializeToString())
        output = anki.decks_pb2.DeckNames()
        output.ParseFromString(raw_bytes)
        return output.entries

    def new_deck_legacy_raw(self, message: bytes) -> bytes:
        return self._run_command(7, 15, message)

    def new_deck_legacy(self, val: bool) -> bytes:
        message = anki.generic_pb2.Bool(val=val)
        raw_bytes = self._run_command(7, 15, message.SerializeToString())
        output = anki.generic_pb2.Json()
        output.ParseFromString(raw_bytes)
        return output.json

    def remove_decks_raw(self, message: bytes) -> bytes:
        return self._run_command(7, 16, message)

    def remove_decks(self, dids: Iterable[int]) -> anki.collection_pb2.OpChangesWithCount:
        message = anki.decks_pb2.DeckIds(dids=dids)
        raw_bytes = self._run_command(7, 16, message.SerializeToString())
        output = anki.collection_pb2.OpChangesWithCount()
        output.ParseFromString(raw_bytes)
        return output

    def reparent_decks_raw(self, message: bytes) -> bytes:
        return self._run_command(7, 17, message)

    def reparent_decks(self, *, deck_ids: Iterable[int], new_parent: int) -> anki.collection_pb2.OpChangesWithCount:
        message = anki.decks_pb2.ReparentDecksRequest(deck_ids=deck_ids, new_parent=new_parent)
        raw_bytes = self._run_command(7, 17, message.SerializeToString())
        output = anki.collection_pb2.OpChangesWithCount()
        output.ParseFromString(raw_bytes)
        return output

    def rename_deck_raw(self, message: bytes) -> bytes:
        return self._run_command(7, 18, message)

    def rename_deck(self, *, deck_id: int, new_name: str) -> anki.collection_pb2.OpChanges:
        message = anki.decks_pb2.RenameDeckRequest(deck_id=deck_id, new_name=new_name)
        raw_bytes = self._run_command(7, 18, message.SerializeToString())
        output = anki.collection_pb2.OpChanges()
        output.ParseFromString(raw_bytes)
        return output

    def get_or_create_filtered_deck_raw(self, message: bytes) -> bytes:
        return self._run_command(7, 19, message)

    def get_or_create_filtered_deck(self, did: int) -> anki.decks_pb2.FilteredDeckForUpdate:
        message = anki.decks_pb2.DeckId(did=did)
        raw_bytes = self._run_command(7, 19, message.SerializeToString())
        output = anki.decks_pb2.FilteredDeckForUpdate()
        output.ParseFromString(raw_bytes)
        return output

    def add_or_update_filtered_deck_raw(self, message: bytes) -> bytes:
        return self._run_command(7, 20, message)

    def add_or_update_filtered_deck(self, message: anki.decks_pb2.FilteredDeckForUpdate) -> anki.collection_pb2.OpChangesWithId:
        
        raw_bytes = self._run_command(7, 20, message.SerializeToString())
        output = anki.collection_pb2.OpChangesWithId()
        output.ParseFromString(raw_bytes)
        return output

    def filtered_deck_order_labels_raw(self, message: bytes) -> bytes:
        return self._run_command(7, 21, message)

    def filtered_deck_order_labels(self) -> Sequence[str]:
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(7, 21, message.SerializeToString())
        output = anki.generic_pb2.StringList()
        output.ParseFromString(raw_bytes)
        return output.vals

    def set_current_deck_raw(self, message: bytes) -> bytes:
        return self._run_command(7, 22, message)

    def set_current_deck(self, did: int) -> anki.collection_pb2.OpChanges:
        message = anki.decks_pb2.DeckId(did=did)
        raw_bytes = self._run_command(7, 22, message.SerializeToString())
        output = anki.collection_pb2.OpChanges()
        output.ParseFromString(raw_bytes)
        return output

    def get_current_deck_raw(self, message: bytes) -> bytes:
        return self._run_command(7, 23, message)

    def get_current_deck(self) -> anki.decks_pb2.Deck:
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(7, 23, message.SerializeToString())
        output = anki.decks_pb2.Deck()
        output.ParseFromString(raw_bytes)
        return output

    def get_config_json_raw(self, message: bytes) -> bytes:
        return self._run_command(9, 0, message)

    def get_config_json(self, val: str) -> bytes:
        message = anki.generic_pb2.String(val=val)
        raw_bytes = self._run_command(9, 0, message.SerializeToString())
        output = anki.generic_pb2.Json()
        output.ParseFromString(raw_bytes)
        return output.json

    def set_config_json_raw(self, message: bytes) -> bytes:
        return self._run_command(9, 1, message)

    def set_config_json(self, *, key: str, value_json: bytes, undoable: bool) -> anki.collection_pb2.OpChanges:
        message = anki.config_pb2.SetConfigJsonRequest(key=key, value_json=value_json, undoable=undoable)
        raw_bytes = self._run_command(9, 1, message.SerializeToString())
        output = anki.collection_pb2.OpChanges()
        output.ParseFromString(raw_bytes)
        return output

    def set_config_json_no_undo_raw(self, message: bytes) -> bytes:
        return self._run_command(9, 2, message)

    def set_config_json_no_undo(self, *, key: str, value_json: bytes, undoable: bool) -> anki.generic_pb2.Empty:
        message = anki.config_pb2.SetConfigJsonRequest(key=key, value_json=value_json, undoable=undoable)
        raw_bytes = self._run_command(9, 2, message.SerializeToString())
        output = anki.generic_pb2.Empty()
        output.ParseFromString(raw_bytes)
        return output

    def remove_config_raw(self, message: bytes) -> bytes:
        return self._run_command(9, 3, message)

    def remove_config(self, val: str) -> anki.collection_pb2.OpChanges:
        message = anki.generic_pb2.String(val=val)
        raw_bytes = self._run_command(9, 3, message.SerializeToString())
        output = anki.collection_pb2.OpChanges()
        output.ParseFromString(raw_bytes)
        return output

    def get_all_config_raw(self, message: bytes) -> bytes:
        return self._run_command(9, 4, message)

    def get_all_config(self) -> bytes:
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(9, 4, message.SerializeToString())
        output = anki.generic_pb2.Json()
        output.ParseFromString(raw_bytes)
        return output.json

    def get_config_bool_raw(self, message: bytes) -> bytes:
        return self._run_command(9, 5, message)

    def get_config_bool(self, key: anki.config_pb2.ConfigKey.Bool.V) -> bool:
        message = anki.config_pb2.GetConfigBoolRequest(key=key)
        raw_bytes = self._run_command(9, 5, message.SerializeToString())
        output = anki.generic_pb2.Bool()
        output.ParseFromString(raw_bytes)
        return output.val

    def set_config_bool_raw(self, message: bytes) -> bytes:
        return self._run_command(9, 6, message)

    def set_config_bool(self, *, key: anki.config_pb2.ConfigKey.Bool.V, value: bool, undoable: bool) -> anki.collection_pb2.OpChanges:
        message = anki.config_pb2.SetConfigBoolRequest(key=key, value=value, undoable=undoable)
        raw_bytes = self._run_command(9, 6, message.SerializeToString())
        output = anki.collection_pb2.OpChanges()
        output.ParseFromString(raw_bytes)
        return output

    def get_config_string_raw(self, message: bytes) -> bytes:
        return self._run_command(9, 7, message)

    def get_config_string(self, key: anki.config_pb2.ConfigKey.String.V) -> str:
        message = anki.config_pb2.GetConfigStringRequest(key=key)
        raw_bytes = self._run_command(9, 7, message.SerializeToString())
        output = anki.generic_pb2.String()
        output.ParseFromString(raw_bytes)
        return output.val

    def set_config_string_raw(self, message: bytes) -> bytes:
        return self._run_command(9, 8, message)

    def set_config_string(self, *, key: anki.config_pb2.ConfigKey.String.V, value: str, undoable: bool) -> anki.collection_pb2.OpChanges:
        message = anki.config_pb2.SetConfigStringRequest(key=key, value=value, undoable=undoable)
        raw_bytes = self._run_command(9, 8, message.SerializeToString())
        output = anki.collection_pb2.OpChanges()
        output.ParseFromString(raw_bytes)
        return output

    def get_preferences_raw(self, message: bytes) -> bytes:
        return self._run_command(9, 9, message)

    def get_preferences(self) -> anki.config_pb2.Preferences:
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(9, 9, message.SerializeToString())
        output = anki.config_pb2.Preferences()
        output.ParseFromString(raw_bytes)
        return output

    def set_preferences_raw(self, message: bytes) -> bytes:
        return self._run_command(9, 10, message)

    def set_preferences(self, message: anki.config_pb2.Preferences) -> anki.collection_pb2.OpChanges:
        
        raw_bytes = self._run_command(9, 10, message.SerializeToString())
        output = anki.collection_pb2.OpChanges()
        output.ParseFromString(raw_bytes)
        return output

    def add_or_update_deck_config_legacy_raw(self, message: bytes) -> bytes:
        return self._run_command(11, 0, message)

    def add_or_update_deck_config_legacy(self, json: bytes) -> int:
        message = anki.generic_pb2.Json(json=json)
        raw_bytes = self._run_command(11, 0, message.SerializeToString())
        output = anki.deck_config_pb2.DeckConfigId()
        output.ParseFromString(raw_bytes)
        return output.dcid

    def get_deck_config_raw(self, message: bytes) -> bytes:
        return self._run_command(11, 1, message)

    def get_deck_config(self, dcid: int) -> anki.deck_config_pb2.DeckConfig:
        message = anki.deck_config_pb2.DeckConfigId(dcid=dcid)
        raw_bytes = self._run_command(11, 1, message.SerializeToString())
        output = anki.deck_config_pb2.DeckConfig()
        output.ParseFromString(raw_bytes)
        return output

    def all_deck_config_legacy_raw(self, message: bytes) -> bytes:
        return self._run_command(11, 2, message)

    def all_deck_config_legacy(self) -> bytes:
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(11, 2, message.SerializeToString())
        output = anki.generic_pb2.Json()
        output.ParseFromString(raw_bytes)
        return output.json

    def get_deck_config_legacy_raw(self, message: bytes) -> bytes:
        return self._run_command(11, 3, message)

    def get_deck_config_legacy(self, dcid: int) -> bytes:
        message = anki.deck_config_pb2.DeckConfigId(dcid=dcid)
        raw_bytes = self._run_command(11, 3, message.SerializeToString())
        output = anki.generic_pb2.Json()
        output.ParseFromString(raw_bytes)
        return output.json

    def new_deck_config_legacy_raw(self, message: bytes) -> bytes:
        return self._run_command(11, 4, message)

    def new_deck_config_legacy(self) -> bytes:
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(11, 4, message.SerializeToString())
        output = anki.generic_pb2.Json()
        output.ParseFromString(raw_bytes)
        return output.json

    def remove_deck_config_raw(self, message: bytes) -> bytes:
        return self._run_command(11, 5, message)

    def remove_deck_config(self, dcid: int) -> anki.generic_pb2.Empty:
        message = anki.deck_config_pb2.DeckConfigId(dcid=dcid)
        raw_bytes = self._run_command(11, 5, message.SerializeToString())
        output = anki.generic_pb2.Empty()
        output.ParseFromString(raw_bytes)
        return output

    def get_deck_configs_for_update_raw(self, message: bytes) -> bytes:
        return self._run_command(11, 6, message)

    def get_deck_configs_for_update(self, did: int) -> anki.deck_config_pb2.DeckConfigsForUpdate:
        message = anki.decks_pb2.DeckId(did=did)
        raw_bytes = self._run_command(11, 6, message.SerializeToString())
        output = anki.deck_config_pb2.DeckConfigsForUpdate()
        output.ParseFromString(raw_bytes)
        return output

    def update_deck_configs_raw(self, message: bytes) -> bytes:
        return self._run_command(11, 7, message)

    def update_deck_configs(self, *, target_deck_id: int, configs: Iterable[anki.deck_config_pb2.DeckConfig], removed_config_ids: Iterable[int], mode: anki.deck_config_pb2.UpdateDeckConfigsMode.V, card_state_customizer: str, limits: anki.deck_config_pb2.DeckConfigsForUpdate.CurrentDeck.Limits, new_cards_ignore_review_limit: bool, fsrs: bool, apply_all_parent_limits: bool, fsrs_reschedule: bool, fsrs_health_check: bool) -> anki.collection_pb2.OpChanges:
        message = anki.deck_config_pb2.UpdateDeckConfigsRequest(target_deck_id=target_deck_id, configs=configs, removed_config_ids=removed_config_ids, mode=mode, card_state_customizer=card_state_customizer, limits=limits, new_cards_ignore_review_limit=new_cards_ignore_review_limit, fsrs=fsrs, apply_all_parent_limits=apply_all_parent_limits, fsrs_reschedule=fsrs_reschedule, fsrs_health_check=fsrs_health_check)
        raw_bytes = self._run_command(11, 7, message.SerializeToString())
        output = anki.collection_pb2.OpChanges()
        output.ParseFromString(raw_bytes)
        return output

    def get_ignored_before_count_raw(self, message: bytes) -> bytes:
        return self._run_command(11, 8, message)

    def get_ignored_before_count(self, *, ignore_revlogs_before_date: str, search: str) -> anki.deck_config_pb2.GetIgnoredBeforeCountResponse:
        message = anki.deck_config_pb2.GetIgnoredBeforeCountRequest(ignore_revlogs_before_date=ignore_revlogs_before_date, search=search)
        raw_bytes = self._run_command(11, 8, message.SerializeToString())
        output = anki.deck_config_pb2.GetIgnoredBeforeCountResponse()
        output.ParseFromString(raw_bytes)
        return output

    def get_retention_workload_raw(self, message: bytes) -> bytes:
        return self._run_command(11, 9, message)

    def get_retention_workload(self, *, w: Iterable[float], search: str) -> Mapping[int, float]:
        message = anki.deck_config_pb2.GetRetentionWorkloadRequest(w=w, search=search)
        raw_bytes = self._run_command(11, 9, message.SerializeToString())
        output = anki.deck_config_pb2.GetRetentionWorkloadResponse()
        output.ParseFromString(raw_bytes)
        return output.costs

    def compute_fsrs_params_from_items_raw(self, message: bytes) -> bytes:
        return self._run_command(13, 0, message)

    def compute_fsrs_params_from_items(self, items: Iterable[anki.scheduler_pb2.FsrsItem]) -> anki.scheduler_pb2.ComputeFsrsParamsResponse:
        message = anki.scheduler_pb2.ComputeFsrsParamsFromItemsRequest(items=items)
        raw_bytes = self._run_command(13, 0, message.SerializeToString())
        output = anki.scheduler_pb2.ComputeFsrsParamsResponse()
        output.ParseFromString(raw_bytes)
        return output

    def fsrs_benchmark_raw(self, message: bytes) -> bytes:
        """Generates parameters used for FSRS's scheduler benchmarks."""
        return self._run_command(13, 1, message)

    def fsrs_benchmark(self, train_set: Iterable[anki.scheduler_pb2.FsrsItem]) -> Sequence[float]:
        """Generates parameters used for FSRS's scheduler benchmarks."""
        message = anki.scheduler_pb2.FsrsBenchmarkRequest(train_set=train_set)
        raw_bytes = self._run_command(13, 1, message.SerializeToString())
        output = anki.scheduler_pb2.FsrsBenchmarkResponse()
        output.ParseFromString(raw_bytes)
        return output.params

    def export_dataset_raw(self, message: bytes) -> bytes:
        """Used for exporting revlogs for algorithm research."""
        return self._run_command(13, 2, message)

    def export_dataset(self, *, min_entries: int, target_path: str) -> anki.generic_pb2.Empty:
        """Used for exporting revlogs for algorithm research."""
        message = anki.scheduler_pb2.ExportDatasetRequest(min_entries=min_entries, target_path=target_path)
        raw_bytes = self._run_command(13, 2, message.SerializeToString())
        output = anki.generic_pb2.Empty()
        output.ParseFromString(raw_bytes)
        return output

    def get_queued_cards_raw(self, message: bytes) -> bytes:
        return self._run_command(13, 3, message)

    def get_queued_cards(self, *, fetch_limit: int, intraday_learning_only: bool) -> anki.scheduler_pb2.QueuedCards:
        message = anki.scheduler_pb2.GetQueuedCardsRequest(fetch_limit=fetch_limit, intraday_learning_only=intraday_learning_only)
        raw_bytes = self._run_command(13, 3, message.SerializeToString())
        output = anki.scheduler_pb2.QueuedCards()
        output.ParseFromString(raw_bytes)
        return output

    def answer_card_raw(self, message: bytes) -> bytes:
        return self._run_command(13, 4, message)

    def answer_card(self, message: anki.scheduler_pb2.CardAnswer) -> anki.collection_pb2.OpChanges:
        
        raw_bytes = self._run_command(13, 4, message.SerializeToString())
        output = anki.collection_pb2.OpChanges()
        output.ParseFromString(raw_bytes)
        return output

    def sched_timing_today_raw(self, message: bytes) -> bytes:
        return self._run_command(13, 5, message)

    def sched_timing_today(self) -> anki.scheduler_pb2.SchedTimingTodayResponse:
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(13, 5, message.SerializeToString())
        output = anki.scheduler_pb2.SchedTimingTodayResponse()
        output.ParseFromString(raw_bytes)
        return output

    def studied_today_raw(self, message: bytes) -> bytes:
        return self._run_command(13, 6, message)

    def studied_today(self) -> str:
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(13, 6, message.SerializeToString())
        output = anki.generic_pb2.String()
        output.ParseFromString(raw_bytes)
        return output.val

    def studied_today_message_raw(self, message: bytes) -> bytes:
        return self._run_command(13, 7, message)

    def studied_today_message(self, *, cards: int, seconds: float) -> str:
        message = anki.scheduler_pb2.StudiedTodayMessageRequest(cards=cards, seconds=seconds)
        raw_bytes = self._run_command(13, 7, message.SerializeToString())
        output = anki.generic_pb2.String()
        output.ParseFromString(raw_bytes)
        return output.val

    def update_stats_raw(self, message: bytes) -> bytes:
        return self._run_command(13, 8, message)

    def update_stats(self, *, deck_id: int, new_delta: int, review_delta: int, millisecond_delta: int) -> anki.generic_pb2.Empty:
        message = anki.scheduler_pb2.UpdateStatsRequest(deck_id=deck_id, new_delta=new_delta, review_delta=review_delta, millisecond_delta=millisecond_delta)
        raw_bytes = self._run_command(13, 8, message.SerializeToString())
        output = anki.generic_pb2.Empty()
        output.ParseFromString(raw_bytes)
        return output

    def extend_limits_raw(self, message: bytes) -> bytes:
        return self._run_command(13, 9, message)

    def extend_limits(self, *, deck_id: int, new_delta: int, review_delta: int) -> anki.generic_pb2.Empty:
        message = anki.scheduler_pb2.ExtendLimitsRequest(deck_id=deck_id, new_delta=new_delta, review_delta=review_delta)
        raw_bytes = self._run_command(13, 9, message.SerializeToString())
        output = anki.generic_pb2.Empty()
        output.ParseFromString(raw_bytes)
        return output

    def counts_for_deck_today_raw(self, message: bytes) -> bytes:
        return self._run_command(13, 10, message)

    def counts_for_deck_today(self, did: int) -> anki.scheduler_pb2.CountsForDeckTodayResponse:
        message = anki.decks_pb2.DeckId(did=did)
        raw_bytes = self._run_command(13, 10, message.SerializeToString())
        output = anki.scheduler_pb2.CountsForDeckTodayResponse()
        output.ParseFromString(raw_bytes)
        return output

    def congrats_info_raw(self, message: bytes) -> bytes:
        return self._run_command(13, 11, message)

    def congrats_info(self) -> anki.scheduler_pb2.CongratsInfoResponse:
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(13, 11, message.SerializeToString())
        output = anki.scheduler_pb2.CongratsInfoResponse()
        output.ParseFromString(raw_bytes)
        return output

    def restore_buried_and_suspended_cards_raw(self, message: bytes) -> bytes:
        return self._run_command(13, 12, message)

    def restore_buried_and_suspended_cards(self, cids: Iterable[int]) -> anki.collection_pb2.OpChanges:
        message = anki.cards_pb2.CardIds(cids=cids)
        raw_bytes = self._run_command(13, 12, message.SerializeToString())
        output = anki.collection_pb2.OpChanges()
        output.ParseFromString(raw_bytes)
        return output

    def unbury_deck_raw(self, message: bytes) -> bytes:
        return self._run_command(13, 13, message)

    def unbury_deck(self, *, deck_id: int, mode: anki.scheduler_pb2.UnburyDeckRequest.Mode.V) -> anki.collection_pb2.OpChanges:
        message = anki.scheduler_pb2.UnburyDeckRequest(deck_id=deck_id, mode=mode)
        raw_bytes = self._run_command(13, 13, message.SerializeToString())
        output = anki.collection_pb2.OpChanges()
        output.ParseFromString(raw_bytes)
        return output

    def bury_or_suspend_cards_raw(self, message: bytes) -> bytes:
        return self._run_command(13, 14, message)

    def bury_or_suspend_cards(self, *, card_ids: Iterable[int], note_ids: Iterable[int], mode: anki.scheduler_pb2.BuryOrSuspendCardsRequest.Mode.V) -> anki.collection_pb2.OpChangesWithCount:
        message = anki.scheduler_pb2.BuryOrSuspendCardsRequest(card_ids=card_ids, note_ids=note_ids, mode=mode)
        raw_bytes = self._run_command(13, 14, message.SerializeToString())
        output = anki.collection_pb2.OpChangesWithCount()
        output.ParseFromString(raw_bytes)
        return output

    def empty_filtered_deck_raw(self, message: bytes) -> bytes:
        return self._run_command(13, 15, message)

    def empty_filtered_deck(self, did: int) -> anki.collection_pb2.OpChanges:
        message = anki.decks_pb2.DeckId(did=did)
        raw_bytes = self._run_command(13, 15, message.SerializeToString())
        output = anki.collection_pb2.OpChanges()
        output.ParseFromString(raw_bytes)
        return output

    def rebuild_filtered_deck_raw(self, message: bytes) -> bytes:
        return self._run_command(13, 16, message)

    def rebuild_filtered_deck(self, did: int) -> anki.collection_pb2.OpChangesWithCount:
        message = anki.decks_pb2.DeckId(did=did)
        raw_bytes = self._run_command(13, 16, message.SerializeToString())
        output = anki.collection_pb2.OpChangesWithCount()
        output.ParseFromString(raw_bytes)
        return output

    def schedule_cards_as_new_raw(self, message: bytes) -> bytes:
        return self._run_command(13, 17, message)

    def schedule_cards_as_new(self, message: anki.scheduler_pb2.ScheduleCardsAsNewRequest) -> anki.collection_pb2.OpChanges:
        
        raw_bytes = self._run_command(13, 17, message.SerializeToString())
        output = anki.collection_pb2.OpChanges()
        output.ParseFromString(raw_bytes)
        return output

    def schedule_cards_as_new_defaults_raw(self, message: bytes) -> bytes:
        return self._run_command(13, 18, message)

    def schedule_cards_as_new_defaults(self, context: anki.scheduler_pb2.ScheduleCardsAsNewRequest.Context.V) -> anki.scheduler_pb2.ScheduleCardsAsNewDefaultsResponse:
        message = anki.scheduler_pb2.ScheduleCardsAsNewDefaultsRequest(context=context)
        raw_bytes = self._run_command(13, 18, message.SerializeToString())
        output = anki.scheduler_pb2.ScheduleCardsAsNewDefaultsResponse()
        output.ParseFromString(raw_bytes)
        return output

    def set_due_date_raw(self, message: bytes) -> bytes:
        return self._run_command(13, 19, message)

    def set_due_date(self, *, card_ids: Iterable[int], days: str, config_key: anki.config_pb2.OptionalStringConfigKey) -> anki.collection_pb2.OpChanges:
        message = anki.scheduler_pb2.SetDueDateRequest(card_ids=card_ids, days=days, config_key=config_key)
        raw_bytes = self._run_command(13, 19, message.SerializeToString())
        output = anki.collection_pb2.OpChanges()
        output.ParseFromString(raw_bytes)
        return output

    def grade_now_raw(self, message: bytes) -> bytes:
        return self._run_command(13, 20, message)

    def grade_now(self, *, card_ids: Iterable[int], rating: anki.scheduler_pb2.CardAnswer.Rating.V) -> anki.collection_pb2.OpChanges:
        message = anki.scheduler_pb2.GradeNowRequest(card_ids=card_ids, rating=rating)
        raw_bytes = self._run_command(13, 20, message.SerializeToString())
        output = anki.collection_pb2.OpChanges()
        output.ParseFromString(raw_bytes)
        return output

    def sort_cards_raw(self, message: bytes) -> bytes:
        return self._run_command(13, 21, message)

    def sort_cards(self, *, card_ids: Iterable[int], starting_from: int, step_size: int, randomize: bool, shift_existing: bool) -> anki.collection_pb2.OpChangesWithCount:
        message = anki.scheduler_pb2.SortCardsRequest(card_ids=card_ids, starting_from=starting_from, step_size=step_size, randomize=randomize, shift_existing=shift_existing)
        raw_bytes = self._run_command(13, 21, message.SerializeToString())
        output = anki.collection_pb2.OpChangesWithCount()
        output.ParseFromString(raw_bytes)
        return output

    def sort_deck_raw(self, message: bytes) -> bytes:
        return self._run_command(13, 22, message)

    def sort_deck(self, *, deck_id: int, randomize: bool) -> anki.collection_pb2.OpChangesWithCount:
        message = anki.scheduler_pb2.SortDeckRequest(deck_id=deck_id, randomize=randomize)
        raw_bytes = self._run_command(13, 22, message.SerializeToString())
        output = anki.collection_pb2.OpChangesWithCount()
        output.ParseFromString(raw_bytes)
        return output

    def get_scheduling_states_raw(self, message: bytes) -> bytes:
        return self._run_command(13, 23, message)

    def get_scheduling_states(self, cid: int) -> anki.scheduler_pb2.SchedulingStates:
        message = anki.cards_pb2.CardId(cid=cid)
        raw_bytes = self._run_command(13, 23, message.SerializeToString())
        output = anki.scheduler_pb2.SchedulingStates()
        output.ParseFromString(raw_bytes)
        return output

    def describe_next_states_raw(self, message: bytes) -> bytes:
        return self._run_command(13, 24, message)

    def describe_next_states(self, message: anki.scheduler_pb2.SchedulingStates) -> Sequence[str]:
        
        raw_bytes = self._run_command(13, 24, message.SerializeToString())
        output = anki.generic_pb2.StringList()
        output.ParseFromString(raw_bytes)
        return output.vals

    def state_is_leech_raw(self, message: bytes) -> bytes:
        return self._run_command(13, 25, message)

    def state_is_leech(self, message: anki.scheduler_pb2.SchedulingState) -> bool:
        
        raw_bytes = self._run_command(13, 25, message.SerializeToString())
        output = anki.generic_pb2.Bool()
        output.ParseFromString(raw_bytes)
        return output.val

    def upgrade_scheduler_raw(self, message: bytes) -> bytes:
        return self._run_command(13, 26, message)

    def upgrade_scheduler(self) -> anki.generic_pb2.Empty:
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(13, 26, message.SerializeToString())
        output = anki.generic_pb2.Empty()
        output.ParseFromString(raw_bytes)
        return output

    def custom_study_raw(self, message: bytes) -> bytes:
        return self._run_command(13, 27, message)

    def custom_study(self, message: anki.scheduler_pb2.CustomStudyRequest) -> anki.collection_pb2.OpChanges:
        
        raw_bytes = self._run_command(13, 27, message.SerializeToString())
        output = anki.collection_pb2.OpChanges()
        output.ParseFromString(raw_bytes)
        return output

    def custom_study_defaults_raw(self, message: bytes) -> bytes:
        return self._run_command(13, 28, message)

    def custom_study_defaults(self, deck_id: int) -> anki.scheduler_pb2.CustomStudyDefaultsResponse:
        message = anki.scheduler_pb2.CustomStudyDefaultsRequest(deck_id=deck_id)
        raw_bytes = self._run_command(13, 28, message.SerializeToString())
        output = anki.scheduler_pb2.CustomStudyDefaultsResponse()
        output.ParseFromString(raw_bytes)
        return output

    def reposition_defaults_raw(self, message: bytes) -> bytes:
        return self._run_command(13, 29, message)

    def reposition_defaults(self) -> anki.scheduler_pb2.RepositionDefaultsResponse:
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(13, 29, message.SerializeToString())
        output = anki.scheduler_pb2.RepositionDefaultsResponse()
        output.ParseFromString(raw_bytes)
        return output

    def compute_fsrs_params_raw(self, message: bytes) -> bytes:
        return self._run_command(13, 30, message)

    def compute_fsrs_params(self, *, search: str, current_params: Iterable[float], ignore_revlogs_before_ms: int, num_of_relearning_steps: int, health_check: bool) -> anki.scheduler_pb2.ComputeFsrsParamsResponse:
        message = anki.scheduler_pb2.ComputeFsrsParamsRequest(search=search, current_params=current_params, ignore_revlogs_before_ms=ignore_revlogs_before_ms, num_of_relearning_steps=num_of_relearning_steps, health_check=health_check)
        raw_bytes = self._run_command(13, 30, message.SerializeToString())
        output = anki.scheduler_pb2.ComputeFsrsParamsResponse()
        output.ParseFromString(raw_bytes)
        return output

    def get_optimal_retention_parameters_raw(self, message: bytes) -> bytes:
        return self._run_command(13, 31, message)

    def get_optimal_retention_parameters(self, search: str) -> anki.scheduler_pb2.GetOptimalRetentionParametersResponse:
        message = anki.scheduler_pb2.GetOptimalRetentionParametersRequest(search=search)
        raw_bytes = self._run_command(13, 31, message.SerializeToString())
        output = anki.scheduler_pb2.GetOptimalRetentionParametersResponse()
        output.ParseFromString(raw_bytes)
        return output

    def compute_optimal_retention_raw(self, message: bytes) -> bytes:
        return self._run_command(13, 32, message)

    def compute_optimal_retention(self, message: anki.scheduler_pb2.SimulateFsrsReviewRequest) -> float:
        
        raw_bytes = self._run_command(13, 32, message.SerializeToString())
        output = anki.scheduler_pb2.ComputeOptimalRetentionResponse()
        output.ParseFromString(raw_bytes)
        return output.optimal_retention

    def simulate_fsrs_review_raw(self, message: bytes) -> bytes:
        return self._run_command(13, 33, message)

    def simulate_fsrs_review(self, message: anki.scheduler_pb2.SimulateFsrsReviewRequest) -> anki.scheduler_pb2.SimulateFsrsReviewResponse:
        
        raw_bytes = self._run_command(13, 33, message.SerializeToString())
        output = anki.scheduler_pb2.SimulateFsrsReviewResponse()
        output.ParseFromString(raw_bytes)
        return output

    def simulate_fsrs_workload_raw(self, message: bytes) -> bytes:
        return self._run_command(13, 34, message)

    def simulate_fsrs_workload(self, message: anki.scheduler_pb2.SimulateFsrsReviewRequest) -> anki.scheduler_pb2.SimulateFsrsWorkloadResponse:
        
        raw_bytes = self._run_command(13, 34, message.SerializeToString())
        output = anki.scheduler_pb2.SimulateFsrsWorkloadResponse()
        output.ParseFromString(raw_bytes)
        return output

    def evaluate_params_raw(self, message: bytes) -> bytes:
        return self._run_command(13, 35, message)

    def evaluate_params(self, *, search: str, ignore_revlogs_before_ms: int, num_of_relearning_steps: int) -> anki.scheduler_pb2.EvaluateParamsResponse:
        message = anki.scheduler_pb2.EvaluateParamsRequest(search=search, ignore_revlogs_before_ms=ignore_revlogs_before_ms, num_of_relearning_steps=num_of_relearning_steps)
        raw_bytes = self._run_command(13, 35, message.SerializeToString())
        output = anki.scheduler_pb2.EvaluateParamsResponse()
        output.ParseFromString(raw_bytes)
        return output

    def evaluate_params_legacy_raw(self, message: bytes) -> bytes:
        return self._run_command(13, 36, message)

    def evaluate_params_legacy(self, *, params: Iterable[float], search: str, ignore_revlogs_before_ms: int) -> anki.scheduler_pb2.EvaluateParamsResponse:
        message = anki.scheduler_pb2.EvaluateParamsLegacyRequest(params=params, search=search, ignore_revlogs_before_ms=ignore_revlogs_before_ms)
        raw_bytes = self._run_command(13, 36, message.SerializeToString())
        output = anki.scheduler_pb2.EvaluateParamsResponse()
        output.ParseFromString(raw_bytes)
        return output

    def compute_memory_state_raw(self, message: bytes) -> bytes:
        return self._run_command(13, 37, message)

    def compute_memory_state(self, cid: int) -> anki.scheduler_pb2.ComputeMemoryStateResponse:
        message = anki.cards_pb2.CardId(cid=cid)
        raw_bytes = self._run_command(13, 37, message.SerializeToString())
        output = anki.scheduler_pb2.ComputeMemoryStateResponse()
        output.ParseFromString(raw_bytes)
        return output

    def fuzz_delta_raw(self, message: bytes) -> bytes:
        """The number of days the calculated interval was fuzzed by on the previous
 review (if any). Utilized by the FSRS add-on."""
        return self._run_command(13, 38, message)

    def fuzz_delta(self, *, card_id: int, interval: int) -> int:
        """The number of days the calculated interval was fuzzed by on the previous
 review (if any). Utilized by the FSRS add-on."""
        message = anki.scheduler_pb2.FuzzDeltaRequest(card_id=card_id, interval=interval)
        raw_bytes = self._run_command(13, 38, message.SerializeToString())
        output = anki.scheduler_pb2.FuzzDeltaResponse()
        output.ParseFromString(raw_bytes)
        return output.delta_days

    def ankihub_login_raw(self, message: bytes) -> bytes:
        return self._run_command(17, 0, message)

    def ankihub_login(self, *, id: str, password: str) -> str:
        message = anki.ankihub_pb2.LoginRequest(id=id, password=password)
        raw_bytes = self._run_command(17, 0, message.SerializeToString())
        output = anki.ankihub_pb2.LoginResponse()
        output.ParseFromString(raw_bytes)
        return output.token

    def ankihub_logout_raw(self, message: bytes) -> bytes:
        return self._run_command(17, 1, message)

    def ankihub_logout(self, token: str) -> anki.generic_pb2.Empty:
        message = anki.ankihub_pb2.LogoutRequest(token=token)
        raw_bytes = self._run_command(17, 1, message.SerializeToString())
        output = anki.generic_pb2.Empty()
        output.ParseFromString(raw_bytes)
        return output

    def get_addon_info_raw(self, message: bytes) -> bytes:
        """Fetch info on add-ons from AnkiWeb. A maximum of 25 can be queried at one
 time. If an add-on doesn't have a branch compatible with the provided
 version, that add-on will not be included in the returned list."""
        return self._run_command(19, 0, message)

    def get_addon_info(self, *, client_version: int, addon_ids: Iterable[int]) -> Sequence[anki.ankiweb_pb2.AddonInfo]:
        """Fetch info on add-ons from AnkiWeb. A maximum of 25 can be queried at one
 time. If an add-on doesn't have a branch compatible with the provided
 version, that add-on will not be included in the returned list."""
        message = anki.ankiweb_pb2.GetAddonInfoRequest(client_version=client_version, addon_ids=addon_ids)
        raw_bytes = self._run_command(19, 0, message.SerializeToString())
        output = anki.ankiweb_pb2.GetAddonInfoResponse()
        output.ParseFromString(raw_bytes)
        return output.info

    def check_for_update_raw(self, message: bytes) -> bytes:
        return self._run_command(19, 1, message)

    def check_for_update(self, *, version: int, buildhash: str, os: str, install_id: int, last_message_id: int) -> anki.ankiweb_pb2.CheckForUpdateResponse:
        message = anki.ankiweb_pb2.CheckForUpdateRequest(version=version, buildhash=buildhash, os=os, install_id=install_id, last_message_id=last_message_id)
        raw_bytes = self._run_command(19, 1, message.SerializeToString())
        output = anki.ankiweb_pb2.CheckForUpdateResponse()
        output.ParseFromString(raw_bytes)
        return output

    def help_page_link_raw(self, message: bytes) -> bytes:
        return self._run_command(21, 0, message)

    def help_page_link(self, page: anki.links_pb2.HelpPageLinkRequest.HelpPage.V) -> str:
        message = anki.links_pb2.HelpPageLinkRequest(page=page)
        raw_bytes = self._run_command(21, 0, message.SerializeToString())
        output = anki.generic_pb2.String()
        output.ParseFromString(raw_bytes)
        return output.val

    def add_notetype_raw(self, message: bytes) -> bytes:
        return self._run_command(23, 0, message)

    def add_notetype(self, message: anki.notetypes_pb2.Notetype) -> anki.collection_pb2.OpChangesWithId:
        
        raw_bytes = self._run_command(23, 0, message.SerializeToString())
        output = anki.collection_pb2.OpChangesWithId()
        output.ParseFromString(raw_bytes)
        return output

    def update_notetype_raw(self, message: bytes) -> bytes:
        return self._run_command(23, 1, message)

    def update_notetype(self, message: anki.notetypes_pb2.Notetype) -> anki.collection_pb2.OpChanges:
        
        raw_bytes = self._run_command(23, 1, message.SerializeToString())
        output = anki.collection_pb2.OpChanges()
        output.ParseFromString(raw_bytes)
        return output

    def add_notetype_legacy_raw(self, message: bytes) -> bytes:
        return self._run_command(23, 2, message)

    def add_notetype_legacy(self, json: bytes) -> anki.collection_pb2.OpChangesWithId:
        message = anki.generic_pb2.Json(json=json)
        raw_bytes = self._run_command(23, 2, message.SerializeToString())
        output = anki.collection_pb2.OpChangesWithId()
        output.ParseFromString(raw_bytes)
        return output

    def update_notetype_legacy_raw(self, message: bytes) -> bytes:
        return self._run_command(23, 3, message)

    def update_notetype_legacy(self, *, json: bytes, skip_checks: bool) -> anki.collection_pb2.OpChanges:
        message = anki.notetypes_pb2.UpdateNotetypeLegacyRequest(json=json, skip_checks=skip_checks)
        raw_bytes = self._run_command(23, 3, message.SerializeToString())
        output = anki.collection_pb2.OpChanges()
        output.ParseFromString(raw_bytes)
        return output

    def add_or_update_notetype_raw(self, message: bytes) -> bytes:
        return self._run_command(23, 4, message)

    def add_or_update_notetype(self, *, json: bytes, preserve_usn_and_mtime: bool, skip_checks: bool) -> int:
        message = anki.notetypes_pb2.AddOrUpdateNotetypeRequest(json=json, preserve_usn_and_mtime=preserve_usn_and_mtime, skip_checks=skip_checks)
        raw_bytes = self._run_command(23, 4, message.SerializeToString())
        output = anki.notetypes_pb2.NotetypeId()
        output.ParseFromString(raw_bytes)
        return output.ntid

    def get_stock_notetype_legacy_raw(self, message: bytes) -> bytes:
        return self._run_command(23, 5, message)

    def get_stock_notetype_legacy(self, kind: anki.notetypes_pb2.StockNotetype.Kind.V) -> bytes:
        message = anki.notetypes_pb2.StockNotetype(kind=kind)
        raw_bytes = self._run_command(23, 5, message.SerializeToString())
        output = anki.generic_pb2.Json()
        output.ParseFromString(raw_bytes)
        return output.json

    def get_notetype_raw(self, message: bytes) -> bytes:
        return self._run_command(23, 6, message)

    def get_notetype(self, ntid: int) -> anki.notetypes_pb2.Notetype:
        message = anki.notetypes_pb2.NotetypeId(ntid=ntid)
        raw_bytes = self._run_command(23, 6, message.SerializeToString())
        output = anki.notetypes_pb2.Notetype()
        output.ParseFromString(raw_bytes)
        return output

    def get_notetype_legacy_raw(self, message: bytes) -> bytes:
        return self._run_command(23, 7, message)

    def get_notetype_legacy(self, ntid: int) -> bytes:
        message = anki.notetypes_pb2.NotetypeId(ntid=ntid)
        raw_bytes = self._run_command(23, 7, message.SerializeToString())
        output = anki.generic_pb2.Json()
        output.ParseFromString(raw_bytes)
        return output.json

    def get_notetype_names_raw(self, message: bytes) -> bytes:
        return self._run_command(23, 8, message)

    def get_notetype_names(self) -> Sequence[anki.notetypes_pb2.NotetypeNameId]:
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(23, 8, message.SerializeToString())
        output = anki.notetypes_pb2.NotetypeNames()
        output.ParseFromString(raw_bytes)
        return output.entries

    def get_notetype_names_and_counts_raw(self, message: bytes) -> bytes:
        return self._run_command(23, 9, message)

    def get_notetype_names_and_counts(self) -> Sequence[anki.notetypes_pb2.NotetypeNameIdUseCount]:
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(23, 9, message.SerializeToString())
        output = anki.notetypes_pb2.NotetypeUseCounts()
        output.ParseFromString(raw_bytes)
        return output.entries

    def get_notetype_id_by_name_raw(self, message: bytes) -> bytes:
        return self._run_command(23, 10, message)

    def get_notetype_id_by_name(self, val: str) -> int:
        message = anki.generic_pb2.String(val=val)
        raw_bytes = self._run_command(23, 10, message.SerializeToString())
        output = anki.notetypes_pb2.NotetypeId()
        output.ParseFromString(raw_bytes)
        return output.ntid

    def remove_notetype_raw(self, message: bytes) -> bytes:
        return self._run_command(23, 11, message)

    def remove_notetype(self, ntid: int) -> anki.collection_pb2.OpChanges:
        message = anki.notetypes_pb2.NotetypeId(ntid=ntid)
        raw_bytes = self._run_command(23, 11, message.SerializeToString())
        output = anki.collection_pb2.OpChanges()
        output.ParseFromString(raw_bytes)
        return output

    def get_aux_notetype_config_key_raw(self, message: bytes) -> bytes:
        return self._run_command(23, 12, message)

    def get_aux_notetype_config_key(self, *, id: int, key: str) -> str:
        message = anki.notetypes_pb2.GetAuxConfigKeyRequest(id=id, key=key)
        raw_bytes = self._run_command(23, 12, message.SerializeToString())
        output = anki.generic_pb2.String()
        output.ParseFromString(raw_bytes)
        return output.val

    def get_aux_template_config_key_raw(self, message: bytes) -> bytes:
        return self._run_command(23, 13, message)

    def get_aux_template_config_key(self, *, notetype_id: int, card_ordinal: int, key: str) -> str:
        message = anki.notetypes_pb2.GetAuxTemplateConfigKeyRequest(notetype_id=notetype_id, card_ordinal=card_ordinal, key=key)
        raw_bytes = self._run_command(23, 13, message.SerializeToString())
        output = anki.generic_pb2.String()
        output.ParseFromString(raw_bytes)
        return output.val

    def get_change_notetype_info_raw(self, message: bytes) -> bytes:
        return self._run_command(23, 14, message)

    def get_change_notetype_info(self, *, old_notetype_id: int, new_notetype_id: int) -> anki.notetypes_pb2.ChangeNotetypeInfo:
        message = anki.notetypes_pb2.GetChangeNotetypeInfoRequest(old_notetype_id=old_notetype_id, new_notetype_id=new_notetype_id)
        raw_bytes = self._run_command(23, 14, message.SerializeToString())
        output = anki.notetypes_pb2.ChangeNotetypeInfo()
        output.ParseFromString(raw_bytes)
        return output

    def change_notetype_raw(self, message: bytes) -> bytes:
        return self._run_command(23, 15, message)

    def change_notetype(self, *, note_ids: Iterable[int], new_fields: Iterable[int], new_templates: Iterable[int], old_notetype_id: int, new_notetype_id: int, current_schema: int, old_notetype_name: str, is_cloze: bool) -> anki.collection_pb2.OpChanges:
        message = anki.notetypes_pb2.ChangeNotetypeRequest(note_ids=note_ids, new_fields=new_fields, new_templates=new_templates, old_notetype_id=old_notetype_id, new_notetype_id=new_notetype_id, current_schema=current_schema, old_notetype_name=old_notetype_name, is_cloze=is_cloze)
        raw_bytes = self._run_command(23, 15, message.SerializeToString())
        output = anki.collection_pb2.OpChanges()
        output.ParseFromString(raw_bytes)
        return output

    def get_field_names_raw(self, message: bytes) -> bytes:
        return self._run_command(23, 16, message)

    def get_field_names(self, ntid: int) -> Sequence[str]:
        message = anki.notetypes_pb2.NotetypeId(ntid=ntid)
        raw_bytes = self._run_command(23, 16, message.SerializeToString())
        output = anki.generic_pb2.StringList()
        output.ParseFromString(raw_bytes)
        return output.vals

    def restore_notetype_to_stock_raw(self, message: bytes) -> bytes:
        return self._run_command(23, 17, message)

    def restore_notetype_to_stock(self, message: anki.notetypes_pb2.RestoreNotetypeToStockRequest) -> anki.collection_pb2.OpChanges:
        
        raw_bytes = self._run_command(23, 17, message.SerializeToString())
        output = anki.collection_pb2.OpChanges()
        output.ParseFromString(raw_bytes)
        return output

    def get_cloze_field_ords_raw(self, message: bytes) -> bytes:
        return self._run_command(23, 18, message)

    def get_cloze_field_ords(self, ntid: int) -> Sequence[int]:
        message = anki.notetypes_pb2.NotetypeId(ntid=ntid)
        raw_bytes = self._run_command(23, 18, message.SerializeToString())
        output = anki.notetypes_pb2.GetClozeFieldOrdsResponse()
        output.ParseFromString(raw_bytes)
        return output.ords

    def new_note_raw(self, message: bytes) -> bytes:
        return self._run_command(25, 0, message)

    def new_note(self, ntid: int) -> anki.notes_pb2.Note:
        message = anki.notetypes_pb2.NotetypeId(ntid=ntid)
        raw_bytes = self._run_command(25, 0, message.SerializeToString())
        output = anki.notes_pb2.Note()
        output.ParseFromString(raw_bytes)
        return output

    def add_note_raw(self, message: bytes) -> bytes:
        return self._run_command(25, 1, message)

    def add_note(self, *, note: anki.notes_pb2.Note, deck_id: int) -> anki.notes_pb2.AddNoteResponse:
        message = anki.notes_pb2.AddNoteRequest(note=note, deck_id=deck_id)
        raw_bytes = self._run_command(25, 1, message.SerializeToString())
        output = anki.notes_pb2.AddNoteResponse()
        output.ParseFromString(raw_bytes)
        return output

    def add_notes_raw(self, message: bytes) -> bytes:
        return self._run_command(25, 2, message)

    def add_notes(self, requests: Iterable[anki.notes_pb2.AddNoteRequest]) -> anki.notes_pb2.AddNotesResponse:
        message = anki.notes_pb2.AddNotesRequest(requests=requests)
        raw_bytes = self._run_command(25, 2, message.SerializeToString())
        output = anki.notes_pb2.AddNotesResponse()
        output.ParseFromString(raw_bytes)
        return output

    def defaults_for_adding_raw(self, message: bytes) -> bytes:
        return self._run_command(25, 3, message)

    def defaults_for_adding(self, home_deck_of_current_review_card: int) -> anki.notes_pb2.DeckAndNotetype:
        message = anki.notes_pb2.DefaultsForAddingRequest(home_deck_of_current_review_card=home_deck_of_current_review_card)
        raw_bytes = self._run_command(25, 3, message.SerializeToString())
        output = anki.notes_pb2.DeckAndNotetype()
        output.ParseFromString(raw_bytes)
        return output

    def default_deck_for_notetype_raw(self, message: bytes) -> bytes:
        return self._run_command(25, 4, message)

    def default_deck_for_notetype(self, ntid: int) -> int:
        message = anki.notetypes_pb2.NotetypeId(ntid=ntid)
        raw_bytes = self._run_command(25, 4, message.SerializeToString())
        output = anki.decks_pb2.DeckId()
        output.ParseFromString(raw_bytes)
        return output.did

    def update_notes_raw(self, message: bytes) -> bytes:
        return self._run_command(25, 5, message)

    def update_notes(self, *, notes: Iterable[anki.notes_pb2.Note], skip_undo_entry: bool) -> anki.collection_pb2.OpChanges:
        message = anki.notes_pb2.UpdateNotesRequest(notes=notes, skip_undo_entry=skip_undo_entry)
        raw_bytes = self._run_command(25, 5, message.SerializeToString())
        output = anki.collection_pb2.OpChanges()
        output.ParseFromString(raw_bytes)
        return output

    def get_note_raw(self, message: bytes) -> bytes:
        return self._run_command(25, 6, message)

    def get_note(self, nid: int) -> anki.notes_pb2.Note:
        message = anki.notes_pb2.NoteId(nid=nid)
        raw_bytes = self._run_command(25, 6, message.SerializeToString())
        output = anki.notes_pb2.Note()
        output.ParseFromString(raw_bytes)
        return output

    def remove_notes_raw(self, message: bytes) -> bytes:
        return self._run_command(25, 7, message)

    def remove_notes(self, *, note_ids: Iterable[int], card_ids: Iterable[int]) -> anki.collection_pb2.OpChangesWithCount:
        message = anki.notes_pb2.RemoveNotesRequest(note_ids=note_ids, card_ids=card_ids)
        raw_bytes = self._run_command(25, 7, message.SerializeToString())
        output = anki.collection_pb2.OpChangesWithCount()
        output.ParseFromString(raw_bytes)
        return output

    def cloze_numbers_in_note_raw(self, message: bytes) -> bytes:
        return self._run_command(25, 8, message)

    def cloze_numbers_in_note(self, message: anki.notes_pb2.Note) -> Sequence[int]:
        
        raw_bytes = self._run_command(25, 8, message.SerializeToString())
        output = anki.notes_pb2.ClozeNumbersInNoteResponse()
        output.ParseFromString(raw_bytes)
        return output.numbers

    def after_note_updates_raw(self, message: bytes) -> bytes:
        return self._run_command(25, 9, message)

    def after_note_updates(self, *, nids: Iterable[int], mark_notes_modified: bool, generate_cards: bool) -> anki.collection_pb2.OpChangesWithCount:
        message = anki.notes_pb2.AfterNoteUpdatesRequest(nids=nids, mark_notes_modified=mark_notes_modified, generate_cards=generate_cards)
        raw_bytes = self._run_command(25, 9, message.SerializeToString())
        output = anki.collection_pb2.OpChangesWithCount()
        output.ParseFromString(raw_bytes)
        return output

    def field_names_for_notes_raw(self, message: bytes) -> bytes:
        return self._run_command(25, 10, message)

    def field_names_for_notes(self, nids: Iterable[int]) -> Sequence[str]:
        message = anki.notes_pb2.FieldNamesForNotesRequest(nids=nids)
        raw_bytes = self._run_command(25, 10, message.SerializeToString())
        output = anki.notes_pb2.FieldNamesForNotesResponse()
        output.ParseFromString(raw_bytes)
        return output.fields

    def note_fields_check_raw(self, message: bytes) -> bytes:
        return self._run_command(25, 11, message)

    def note_fields_check(self, message: anki.notes_pb2.Note) -> anki.notes_pb2.NoteFieldsCheckResponse:
        
        raw_bytes = self._run_command(25, 11, message.SerializeToString())
        output = anki.notes_pb2.NoteFieldsCheckResponse()
        output.ParseFromString(raw_bytes)
        return output

    def cards_of_note_raw(self, message: bytes) -> bytes:
        return self._run_command(25, 12, message)

    def cards_of_note(self, nid: int) -> Sequence[int]:
        message = anki.notes_pb2.NoteId(nid=nid)
        raw_bytes = self._run_command(25, 12, message.SerializeToString())
        output = anki.cards_pb2.CardIds()
        output.ParseFromString(raw_bytes)
        return output.cids

    def get_single_notetype_of_notes_raw(self, message: bytes) -> bytes:
        return self._run_command(25, 13, message)

    def get_single_notetype_of_notes(self, note_ids: Iterable[int]) -> int:
        message = anki.notes_pb2.NoteIds(note_ids=note_ids)
        raw_bytes = self._run_command(25, 13, message.SerializeToString())
        output = anki.notetypes_pb2.NotetypeId()
        output.ParseFromString(raw_bytes)
        return output.ntid

    def strip_html_raw(self, message: bytes) -> bytes:
        return self._run_command(27, 0, message)

    def strip_html(self, *, text: str, mode: anki.card_rendering_pb2.StripHtmlRequest.Mode.V) -> str:
        message = anki.card_rendering_pb2.StripHtmlRequest(text=text, mode=mode)
        raw_bytes = self._run_command(27, 0, message.SerializeToString())
        output = anki.generic_pb2.String()
        output.ParseFromString(raw_bytes)
        return output.val

    def all_tts_voices_raw(self, message: bytes) -> bytes:
        return self._run_command(27, 1, message)

    def all_tts_voices(self, validate: bool) -> Sequence[anki.card_rendering_pb2.AllTtsVoicesResponse.TtsVoice]:
        message = anki.card_rendering_pb2.AllTtsVoicesRequest(validate=validate)
        raw_bytes = self._run_command(27, 1, message.SerializeToString())
        output = anki.card_rendering_pb2.AllTtsVoicesResponse()
        output.ParseFromString(raw_bytes)
        return output.voices

    def write_tts_stream_raw(self, message: bytes) -> bytes:
        return self._run_command(27, 2, message)

    def write_tts_stream(self, *, path: str, voice_id: str, speed: float, text: str) -> anki.generic_pb2.Empty:
        message = anki.card_rendering_pb2.WriteTtsStreamRequest(path=path, voice_id=voice_id, speed=speed, text=text)
        raw_bytes = self._run_command(27, 2, message.SerializeToString())
        output = anki.generic_pb2.Empty()
        output.ParseFromString(raw_bytes)
        return output

    def extract_av_tags_raw(self, message: bytes) -> bytes:
        return self._run_command(27, 3, message)

    def extract_av_tags(self, *, text: str, question_side: bool) -> anki.card_rendering_pb2.ExtractAvTagsResponse:
        message = anki.card_rendering_pb2.ExtractAvTagsRequest(text=text, question_side=question_side)
        raw_bytes = self._run_command(27, 3, message.SerializeToString())
        output = anki.card_rendering_pb2.ExtractAvTagsResponse()
        output.ParseFromString(raw_bytes)
        return output

    def extract_latex_raw(self, message: bytes) -> bytes:
        return self._run_command(27, 4, message)

    def extract_latex(self, *, text: str, svg: bool, expand_clozes: bool) -> anki.card_rendering_pb2.ExtractLatexResponse:
        message = anki.card_rendering_pb2.ExtractLatexRequest(text=text, svg=svg, expand_clozes=expand_clozes)
        raw_bytes = self._run_command(27, 4, message.SerializeToString())
        output = anki.card_rendering_pb2.ExtractLatexResponse()
        output.ParseFromString(raw_bytes)
        return output

    def get_empty_cards_raw(self, message: bytes) -> bytes:
        return self._run_command(27, 5, message)

    def get_empty_cards(self) -> anki.card_rendering_pb2.EmptyCardsReport:
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(27, 5, message.SerializeToString())
        output = anki.card_rendering_pb2.EmptyCardsReport()
        output.ParseFromString(raw_bytes)
        return output

    def render_existing_card_raw(self, message: bytes) -> bytes:
        return self._run_command(27, 6, message)

    def render_existing_card(self, *, card_id: int, browser: bool, partial_render: bool) -> anki.card_rendering_pb2.RenderCardResponse:
        message = anki.card_rendering_pb2.RenderExistingCardRequest(card_id=card_id, browser=browser, partial_render=partial_render)
        raw_bytes = self._run_command(27, 6, message.SerializeToString())
        output = anki.card_rendering_pb2.RenderCardResponse()
        output.ParseFromString(raw_bytes)
        return output

    def render_uncommitted_card_raw(self, message: bytes) -> bytes:
        return self._run_command(27, 7, message)

    def render_uncommitted_card(self, *, note: anki.notes_pb2.Note, card_ord: int, template: anki.notetypes_pb2.Notetype.Template, fill_empty: bool, partial_render: bool) -> anki.card_rendering_pb2.RenderCardResponse:
        message = anki.card_rendering_pb2.RenderUncommittedCardRequest(note=note, card_ord=card_ord, template=template, fill_empty=fill_empty, partial_render=partial_render)
        raw_bytes = self._run_command(27, 7, message.SerializeToString())
        output = anki.card_rendering_pb2.RenderCardResponse()
        output.ParseFromString(raw_bytes)
        return output

    def render_uncommitted_card_legacy_raw(self, message: bytes) -> bytes:
        return self._run_command(27, 8, message)

    def render_uncommitted_card_legacy(self, *, note: anki.notes_pb2.Note, card_ord: int, template: bytes, fill_empty: bool, partial_render: bool) -> anki.card_rendering_pb2.RenderCardResponse:
        message = anki.card_rendering_pb2.RenderUncommittedCardLegacyRequest(note=note, card_ord=card_ord, template=template, fill_empty=fill_empty, partial_render=partial_render)
        raw_bytes = self._run_command(27, 8, message.SerializeToString())
        output = anki.card_rendering_pb2.RenderCardResponse()
        output.ParseFromString(raw_bytes)
        return output

    def strip_av_tags_raw(self, message: bytes) -> bytes:
        return self._run_command(27, 9, message)

    def strip_av_tags(self, val: str) -> str:
        message = anki.generic_pb2.String(val=val)
        raw_bytes = self._run_command(27, 9, message.SerializeToString())
        output = anki.generic_pb2.String()
        output.ParseFromString(raw_bytes)
        return output.val

    def render_markdown_raw(self, message: bytes) -> bytes:
        return self._run_command(27, 10, message)

    def render_markdown(self, *, markdown: str, sanitize: bool) -> str:
        message = anki.card_rendering_pb2.RenderMarkdownRequest(markdown=markdown, sanitize=sanitize)
        raw_bytes = self._run_command(27, 10, message.SerializeToString())
        output = anki.generic_pb2.String()
        output.ParseFromString(raw_bytes)
        return output.val

    def encode_iri_paths_raw(self, message: bytes) -> bytes:
        return self._run_command(27, 11, message)

    def encode_iri_paths(self, val: str) -> str:
        message = anki.generic_pb2.String(val=val)
        raw_bytes = self._run_command(27, 11, message.SerializeToString())
        output = anki.generic_pb2.String()
        output.ParseFromString(raw_bytes)
        return output.val

    def decode_iri_paths_raw(self, message: bytes) -> bytes:
        return self._run_command(27, 12, message)

    def decode_iri_paths(self, val: str) -> str:
        message = anki.generic_pb2.String(val=val)
        raw_bytes = self._run_command(27, 12, message.SerializeToString())
        output = anki.generic_pb2.String()
        output.ParseFromString(raw_bytes)
        return output.val

    def html_to_text_line_raw(self, message: bytes) -> bytes:
        return self._run_command(27, 14, message)

    def html_to_text_line(self, *, text: str, preserve_media_filenames: bool) -> str:
        message = anki.card_rendering_pb2.HtmlToTextLineRequest(text=text, preserve_media_filenames=preserve_media_filenames)
        raw_bytes = self._run_command(27, 14, message.SerializeToString())
        output = anki.generic_pb2.String()
        output.ParseFromString(raw_bytes)
        return output.val

    def compare_answer_raw(self, message: bytes) -> bytes:
        return self._run_command(27, 15, message)

    def compare_answer(self, *, expected: str, provided: str, combining: bool) -> str:
        message = anki.card_rendering_pb2.CompareAnswerRequest(expected=expected, provided=provided, combining=combining)
        raw_bytes = self._run_command(27, 15, message.SerializeToString())
        output = anki.generic_pb2.String()
        output.ParseFromString(raw_bytes)
        return output.val

    def extract_cloze_for_typing_raw(self, message: bytes) -> bytes:
        return self._run_command(27, 16, message)

    def extract_cloze_for_typing(self, *, text: str, ordinal: int) -> str:
        message = anki.card_rendering_pb2.ExtractClozeForTypingRequest(text=text, ordinal=ordinal)
        raw_bytes = self._run_command(27, 16, message.SerializeToString())
        output = anki.generic_pb2.String()
        output.ParseFromString(raw_bytes)
        return output.val

    def build_search_string_raw(self, message: bytes) -> bytes:
        return self._run_command(29, 0, message)

    def build_search_string(self, message: anki.search_pb2.SearchNode) -> str:
        
        raw_bytes = self._run_command(29, 0, message.SerializeToString())
        output = anki.generic_pb2.String()
        output.ParseFromString(raw_bytes)
        return output.val

    def search_cards_raw(self, message: bytes) -> bytes:
        return self._run_command(29, 1, message)

    def search_cards(self, *, search: str, order: anki.search_pb2.SortOrder) -> Sequence[int]:
        message = anki.search_pb2.SearchRequest(search=search, order=order)
        raw_bytes = self._run_command(29, 1, message.SerializeToString())
        output = anki.search_pb2.SearchResponse()
        output.ParseFromString(raw_bytes)
        return output.ids

    def search_notes_raw(self, message: bytes) -> bytes:
        return self._run_command(29, 2, message)

    def search_notes(self, *, search: str, order: anki.search_pb2.SortOrder) -> Sequence[int]:
        message = anki.search_pb2.SearchRequest(search=search, order=order)
        raw_bytes = self._run_command(29, 2, message.SerializeToString())
        output = anki.search_pb2.SearchResponse()
        output.ParseFromString(raw_bytes)
        return output.ids

    def join_search_nodes_raw(self, message: bytes) -> bytes:
        return self._run_command(29, 3, message)

    def join_search_nodes(self, *, joiner: anki.search_pb2.SearchNode.Group.Joiner.V, existing_node: anki.search_pb2.SearchNode, additional_node: anki.search_pb2.SearchNode) -> str:
        message = anki.search_pb2.JoinSearchNodesRequest(joiner=joiner, existing_node=existing_node, additional_node=additional_node)
        raw_bytes = self._run_command(29, 3, message.SerializeToString())
        output = anki.generic_pb2.String()
        output.ParseFromString(raw_bytes)
        return output.val

    def replace_search_node_raw(self, message: bytes) -> bytes:
        return self._run_command(29, 4, message)

    def replace_search_node(self, *, existing_node: anki.search_pb2.SearchNode, replacement_node: anki.search_pb2.SearchNode) -> str:
        message = anki.search_pb2.ReplaceSearchNodeRequest(existing_node=existing_node, replacement_node=replacement_node)
        raw_bytes = self._run_command(29, 4, message.SerializeToString())
        output = anki.generic_pb2.String()
        output.ParseFromString(raw_bytes)
        return output.val

    def find_and_replace_raw(self, message: bytes) -> bytes:
        return self._run_command(29, 5, message)

    def find_and_replace(self, *, nids: Iterable[int], search: str, replacement: str, regex: bool, match_case: bool, field_name: str) -> anki.collection_pb2.OpChangesWithCount:
        message = anki.search_pb2.FindAndReplaceRequest(nids=nids, search=search, replacement=replacement, regex=regex, match_case=match_case, field_name=field_name)
        raw_bytes = self._run_command(29, 5, message.SerializeToString())
        output = anki.collection_pb2.OpChangesWithCount()
        output.ParseFromString(raw_bytes)
        return output

    def all_browser_columns_raw(self, message: bytes) -> bytes:
        return self._run_command(29, 6, message)

    def all_browser_columns(self) -> Sequence[anki.search_pb2.BrowserColumns.Column]:
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(29, 6, message.SerializeToString())
        output = anki.search_pb2.BrowserColumns()
        output.ParseFromString(raw_bytes)
        return output.columns

    def browser_row_for_id_raw(self, message: bytes) -> bytes:
        return self._run_command(29, 7, message)

    def browser_row_for_id(self, val: int) -> anki.search_pb2.BrowserRow:
        message = anki.generic_pb2.Int64(val=val)
        raw_bytes = self._run_command(29, 7, message.SerializeToString())
        output = anki.search_pb2.BrowserRow()
        output.ParseFromString(raw_bytes)
        return output

    def set_active_browser_columns_raw(self, message: bytes) -> bytes:
        return self._run_command(29, 8, message)

    def set_active_browser_columns(self, vals: Iterable[str]) -> anki.generic_pb2.Empty:
        message = anki.generic_pb2.StringList(vals=vals)
        raw_bytes = self._run_command(29, 8, message.SerializeToString())
        output = anki.generic_pb2.Empty()
        output.ParseFromString(raw_bytes)
        return output

    def get_scheduling_states_with_context_raw(self, message: bytes) -> bytes:
        """Returns values from the reviewer"""
        return self._run_command(31, 0, message)

    def get_scheduling_states_with_context(self) -> anki.frontend_pb2.SchedulingStatesWithContext:
        """Returns values from the reviewer"""
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(31, 0, message.SerializeToString())
        output = anki.frontend_pb2.SchedulingStatesWithContext()
        output.ParseFromString(raw_bytes)
        return output

    def set_scheduling_states_raw(self, message: bytes) -> bytes:
        """Updates reviewer state"""
        return self._run_command(31, 1, message)

    def set_scheduling_states(self, *, key: str, states: anki.scheduler_pb2.SchedulingStates) -> anki.generic_pb2.Empty:
        """Updates reviewer state"""
        message = anki.frontend_pb2.SetSchedulingStatesRequest(key=key, states=states)
        raw_bytes = self._run_command(31, 1, message.SerializeToString())
        output = anki.generic_pb2.Empty()
        output.ParseFromString(raw_bytes)
        return output

    def import_done_raw(self, message: bytes) -> bytes:
        """Notify Qt layer so window modality can be updated."""
        return self._run_command(31, 2, message)

    def import_done(self) -> anki.generic_pb2.Empty:
        """Notify Qt layer so window modality can be updated."""
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(31, 2, message.SerializeToString())
        output = anki.generic_pb2.Empty()
        output.ParseFromString(raw_bytes)
        return output

    def search_in_browser_raw(self, message: bytes) -> bytes:
        return self._run_command(31, 3, message)

    def search_in_browser(self, message: anki.search_pb2.SearchNode) -> anki.generic_pb2.Empty:
        
        raw_bytes = self._run_command(31, 3, message.SerializeToString())
        output = anki.generic_pb2.Empty()
        output.ParseFromString(raw_bytes)
        return output

    def deck_options_require_close_raw(self, message: bytes) -> bytes:
        """Force closing the deck options."""
        return self._run_command(31, 4, message)

    def deck_options_require_close(self) -> anki.generic_pb2.Empty:
        """Force closing the deck options."""
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(31, 4, message.SerializeToString())
        output = anki.generic_pb2.Empty()
        output.ParseFromString(raw_bytes)
        return output

    def deck_options_ready_raw(self, message: bytes) -> bytes:
        """Warns python that the deck option web view is ready to receive requests."""
        return self._run_command(31, 5, message)

    def deck_options_ready(self) -> anki.generic_pb2.Empty:
        """Warns python that the deck option web view is ready to receive requests."""
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(31, 5, message.SerializeToString())
        output = anki.generic_pb2.Empty()
        output.ParseFromString(raw_bytes)
        return output

    def save_custom_colours_raw(self, message: bytes) -> bytes:
        """Save colour picker's custom colour palette"""
        return self._run_command(31, 6, message)

    def save_custom_colours(self) -> anki.generic_pb2.Empty:
        """Save colour picker's custom colour palette"""
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(31, 6, message.SerializeToString())
        output = anki.generic_pb2.Empty()
        output.ParseFromString(raw_bytes)
        return output

    def translate_string_raw(self, message: bytes) -> bytes:
        return self._run_command(33, 0, message)

    def translate_string(self, *, module_index: int, message_index: int, args: Mapping[str, anki.i18n_pb2.TranslateArgValue]) -> str:
        message = anki.i18n_pb2.TranslateStringRequest(module_index=module_index, message_index=message_index, args=args)
        raw_bytes = self._run_command(33, 0, message.SerializeToString())
        output = anki.generic_pb2.String()
        output.ParseFromString(raw_bytes)
        return output.val

    def format_timespan_raw(self, message: bytes) -> bytes:
        return self._run_command(33, 1, message)

    def format_timespan(self, *, seconds: float, context: anki.i18n_pb2.FormatTimespanRequest.Context.V) -> str:
        message = anki.i18n_pb2.FormatTimespanRequest(seconds=seconds, context=context)
        raw_bytes = self._run_command(33, 1, message.SerializeToString())
        output = anki.generic_pb2.String()
        output.ParseFromString(raw_bytes)
        return output.val

    def i18n_resources_raw(self, message: bytes) -> bytes:
        return self._run_command(33, 2, message)

    def i18n_resources(self, modules: Iterable[str]) -> bytes:
        message = anki.i18n_pb2.I18nResourcesRequest(modules=modules)
        raw_bytes = self._run_command(33, 2, message.SerializeToString())
        output = anki.generic_pb2.Json()
        output.ParseFromString(raw_bytes)
        return output.json

    def get_image_for_occlusion_raw(self, message: bytes) -> bytes:
        return self._run_command(35, 0, message)

    def get_image_for_occlusion(self, path: str) -> anki.image_occlusion_pb2.GetImageForOcclusionResponse:
        message = anki.image_occlusion_pb2.GetImageForOcclusionRequest(path=path)
        raw_bytes = self._run_command(35, 0, message.SerializeToString())
        output = anki.image_occlusion_pb2.GetImageForOcclusionResponse()
        output.ParseFromString(raw_bytes)
        return output

    def get_image_occlusion_note_raw(self, message: bytes) -> bytes:
        return self._run_command(35, 1, message)

    def get_image_occlusion_note(self, note_id: int) -> anki.image_occlusion_pb2.GetImageOcclusionNoteResponse:
        message = anki.image_occlusion_pb2.GetImageOcclusionNoteRequest(note_id=note_id)
        raw_bytes = self._run_command(35, 1, message.SerializeToString())
        output = anki.image_occlusion_pb2.GetImageOcclusionNoteResponse()
        output.ParseFromString(raw_bytes)
        return output

    def get_image_occlusion_fields_raw(self, message: bytes) -> bytes:
        return self._run_command(35, 2, message)

    def get_image_occlusion_fields(self, notetype_id: int) -> anki.image_occlusion_pb2.ImageOcclusionFieldIndexes:
        message = anki.image_occlusion_pb2.GetImageOcclusionFieldsRequest(notetype_id=notetype_id)
        raw_bytes = self._run_command(35, 2, message.SerializeToString())
        output = anki.image_occlusion_pb2.GetImageOcclusionFieldsResponse()
        output.ParseFromString(raw_bytes)
        return output.fields

    def add_image_occlusion_notetype_raw(self, message: bytes) -> bytes:
        """Adds an I/O notetype if none exists in the collection."""
        return self._run_command(35, 3, message)

    def add_image_occlusion_notetype(self) -> anki.collection_pb2.OpChanges:
        """Adds an I/O notetype if none exists in the collection."""
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(35, 3, message.SerializeToString())
        output = anki.collection_pb2.OpChanges()
        output.ParseFromString(raw_bytes)
        return output

    def add_image_occlusion_note_raw(self, message: bytes) -> bytes:
        """These two are used by the standalone I/O page, but not used when using
 I/O inside Anki's editor"""
        return self._run_command(35, 4, message)

    def add_image_occlusion_note(self, *, image_path: str, occlusions: str, header: str, back_extra: str, tags: Iterable[str], notetype_id: int) -> anki.collection_pb2.OpChanges:
        """These two are used by the standalone I/O page, but not used when using
 I/O inside Anki's editor"""
        message = anki.image_occlusion_pb2.AddImageOcclusionNoteRequest(image_path=image_path, occlusions=occlusions, header=header, back_extra=back_extra, tags=tags, notetype_id=notetype_id)
        raw_bytes = self._run_command(35, 4, message.SerializeToString())
        output = anki.collection_pb2.OpChanges()
        output.ParseFromString(raw_bytes)
        return output

    def update_image_occlusion_note_raw(self, message: bytes) -> bytes:
        return self._run_command(35, 5, message)

    def update_image_occlusion_note(self, *, note_id: int, occlusions: str, header: str, back_extra: str, tags: Iterable[str]) -> anki.collection_pb2.OpChanges:
        message = anki.image_occlusion_pb2.UpdateImageOcclusionNoteRequest(note_id=note_id, occlusions=occlusions, header=header, back_extra=back_extra, tags=tags)
        raw_bytes = self._run_command(35, 5, message.SerializeToString())
        output = anki.collection_pb2.OpChanges()
        output.ParseFromString(raw_bytes)
        return output

    def import_collection_package_raw(self, message: bytes) -> bytes:
        return self._run_command(37, 0, message)

    def import_collection_package(self, *, col_path: str, backup_path: str, media_folder: str, media_db: str) -> anki.generic_pb2.Empty:
        message = anki.import_export_pb2.ImportCollectionPackageRequest(col_path=col_path, backup_path=backup_path, media_folder=media_folder, media_db=media_db)
        raw_bytes = self._run_command(37, 0, message.SerializeToString())
        output = anki.generic_pb2.Empty()
        output.ParseFromString(raw_bytes)
        return output

    def export_collection_package_raw(self, message: bytes) -> bytes:
        return self._run_command(37, 1, message)

    def export_collection_package(self, *, out_path: str, include_media: bool, legacy: bool) -> anki.generic_pb2.Empty:
        message = anki.import_export_pb2.ExportCollectionPackageRequest(out_path=out_path, include_media=include_media, legacy=legacy)
        raw_bytes = self._run_command(37, 1, message.SerializeToString())
        output = anki.generic_pb2.Empty()
        output.ParseFromString(raw_bytes)
        return output

    def import_anki_package_raw(self, message: bytes) -> bytes:
        return self._run_command(37, 2, message)

    def import_anki_package(self, *, package_path: str, options: anki.import_export_pb2.ImportAnkiPackageOptions) -> anki.import_export_pb2.ImportResponse:
        message = anki.import_export_pb2.ImportAnkiPackageRequest(package_path=package_path, options=options)
        raw_bytes = self._run_command(37, 2, message.SerializeToString())
        output = anki.import_export_pb2.ImportResponse()
        output.ParseFromString(raw_bytes)
        return output

    def get_import_anki_package_presets_raw(self, message: bytes) -> bytes:
        return self._run_command(37, 3, message)

    def get_import_anki_package_presets(self) -> anki.import_export_pb2.ImportAnkiPackageOptions:
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(37, 3, message.SerializeToString())
        output = anki.import_export_pb2.ImportAnkiPackageOptions()
        output.ParseFromString(raw_bytes)
        return output

    def export_anki_package_raw(self, message: bytes) -> bytes:
        return self._run_command(37, 4, message)

    def export_anki_package(self, *, out_path: str, options: anki.import_export_pb2.ExportAnkiPackageOptions, limit: anki.import_export_pb2.ExportLimit) -> int:
        message = anki.import_export_pb2.ExportAnkiPackageRequest(out_path=out_path, options=options, limit=limit)
        raw_bytes = self._run_command(37, 4, message.SerializeToString())
        output = anki.generic_pb2.UInt32()
        output.ParseFromString(raw_bytes)
        return output.val

    def get_csv_metadata_raw(self, message: bytes) -> bytes:
        return self._run_command(37, 5, message)

    def get_csv_metadata(self, message: anki.import_export_pb2.CsvMetadataRequest) -> anki.import_export_pb2.CsvMetadata:
        
        raw_bytes = self._run_command(37, 5, message.SerializeToString())
        output = anki.import_export_pb2.CsvMetadata()
        output.ParseFromString(raw_bytes)
        return output

    def import_csv_raw(self, message: bytes) -> bytes:
        return self._run_command(37, 6, message)

    def import_csv(self, *, path: str, metadata: anki.import_export_pb2.CsvMetadata) -> anki.import_export_pb2.ImportResponse:
        message = anki.import_export_pb2.ImportCsvRequest(path=path, metadata=metadata)
        raw_bytes = self._run_command(37, 6, message.SerializeToString())
        output = anki.import_export_pb2.ImportResponse()
        output.ParseFromString(raw_bytes)
        return output

    def export_note_csv_raw(self, message: bytes) -> bytes:
        return self._run_command(37, 7, message)

    def export_note_csv(self, *, out_path: str, with_html: bool, with_tags: bool, with_deck: bool, with_notetype: bool, with_guid: bool, limit: anki.import_export_pb2.ExportLimit) -> int:
        message = anki.import_export_pb2.ExportNoteCsvRequest(out_path=out_path, with_html=with_html, with_tags=with_tags, with_deck=with_deck, with_notetype=with_notetype, with_guid=with_guid, limit=limit)
        raw_bytes = self._run_command(37, 7, message.SerializeToString())
        output = anki.generic_pb2.UInt32()
        output.ParseFromString(raw_bytes)
        return output.val

    def export_card_csv_raw(self, message: bytes) -> bytes:
        return self._run_command(37, 8, message)

    def export_card_csv(self, *, out_path: str, with_html: bool, limit: anki.import_export_pb2.ExportLimit) -> int:
        message = anki.import_export_pb2.ExportCardCsvRequest(out_path=out_path, with_html=with_html, limit=limit)
        raw_bytes = self._run_command(37, 8, message.SerializeToString())
        output = anki.generic_pb2.UInt32()
        output.ParseFromString(raw_bytes)
        return output.val

    def import_json_file_raw(self, message: bytes) -> bytes:
        return self._run_command(37, 9, message)

    def import_json_file(self, val: str) -> anki.import_export_pb2.ImportResponse:
        message = anki.generic_pb2.String(val=val)
        raw_bytes = self._run_command(37, 9, message.SerializeToString())
        output = anki.import_export_pb2.ImportResponse()
        output.ParseFromString(raw_bytes)
        return output

    def import_json_string_raw(self, message: bytes) -> bytes:
        return self._run_command(37, 10, message)

    def import_json_string(self, val: str) -> anki.import_export_pb2.ImportResponse:
        message = anki.generic_pb2.String(val=val)
        raw_bytes = self._run_command(37, 10, message.SerializeToString())
        output = anki.import_export_pb2.ImportResponse()
        output.ParseFromString(raw_bytes)
        return output

    def check_media_raw(self, message: bytes) -> bytes:
        return self._run_command(39, 0, message)

    def check_media(self) -> anki.media_pb2.CheckMediaResponse:
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(39, 0, message.SerializeToString())
        output = anki.media_pb2.CheckMediaResponse()
        output.ParseFromString(raw_bytes)
        return output

    def add_media_file_raw(self, message: bytes) -> bytes:
        return self._run_command(39, 1, message)

    def add_media_file(self, *, desired_name: str, data: bytes) -> str:
        message = anki.media_pb2.AddMediaFileRequest(desired_name=desired_name, data=data)
        raw_bytes = self._run_command(39, 1, message.SerializeToString())
        output = anki.generic_pb2.String()
        output.ParseFromString(raw_bytes)
        return output.val

    def trash_media_files_raw(self, message: bytes) -> bytes:
        return self._run_command(39, 2, message)

    def trash_media_files(self, fnames: Iterable[str]) -> anki.generic_pb2.Empty:
        message = anki.media_pb2.TrashMediaFilesRequest(fnames=fnames)
        raw_bytes = self._run_command(39, 2, message.SerializeToString())
        output = anki.generic_pb2.Empty()
        output.ParseFromString(raw_bytes)
        return output

    def empty_trash_raw(self, message: bytes) -> bytes:
        return self._run_command(39, 3, message)

    def empty_trash(self) -> anki.generic_pb2.Empty:
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(39, 3, message.SerializeToString())
        output = anki.generic_pb2.Empty()
        output.ParseFromString(raw_bytes)
        return output

    def restore_trash_raw(self, message: bytes) -> bytes:
        return self._run_command(39, 4, message)

    def restore_trash(self) -> anki.generic_pb2.Empty:
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(39, 4, message.SerializeToString())
        output = anki.generic_pb2.Empty()
        output.ParseFromString(raw_bytes)
        return output

    def extract_static_media_files_raw(self, message: bytes) -> bytes:
        return self._run_command(39, 5, message)

    def extract_static_media_files(self, ntid: int) -> Sequence[str]:
        message = anki.notetypes_pb2.NotetypeId(ntid=ntid)
        raw_bytes = self._run_command(39, 5, message.SerializeToString())
        output = anki.generic_pb2.StringList()
        output.ParseFromString(raw_bytes)
        return output.vals

    def card_stats_raw(self, message: bytes) -> bytes:
        return self._run_command(41, 0, message)

    def card_stats(self, cid: int) -> anki.stats_pb2.CardStatsResponse:
        message = anki.cards_pb2.CardId(cid=cid)
        raw_bytes = self._run_command(41, 0, message.SerializeToString())
        output = anki.stats_pb2.CardStatsResponse()
        output.ParseFromString(raw_bytes)
        return output

    def get_review_logs_raw(self, message: bytes) -> bytes:
        return self._run_command(41, 1, message)

    def get_review_logs(self, cid: int) -> Sequence[anki.stats_pb2.CardStatsResponse.StatsRevlogEntry]:
        message = anki.cards_pb2.CardId(cid=cid)
        raw_bytes = self._run_command(41, 1, message.SerializeToString())
        output = anki.stats_pb2.ReviewLogs()
        output.ParseFromString(raw_bytes)
        return output.entries

    def graphs_raw(self, message: bytes) -> bytes:
        return self._run_command(41, 2, message)

    def graphs(self, *, search: str, days: int) -> anki.stats_pb2.GraphsResponse:
        message = anki.stats_pb2.GraphsRequest(search=search, days=days)
        raw_bytes = self._run_command(41, 2, message.SerializeToString())
        output = anki.stats_pb2.GraphsResponse()
        output.ParseFromString(raw_bytes)
        return output

    def get_graph_preferences_raw(self, message: bytes) -> bytes:
        return self._run_command(41, 3, message)

    def get_graph_preferences(self) -> anki.stats_pb2.GraphPreferences:
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(41, 3, message.SerializeToString())
        output = anki.stats_pb2.GraphPreferences()
        output.ParseFromString(raw_bytes)
        return output

    def set_graph_preferences_raw(self, message: bytes) -> bytes:
        return self._run_command(41, 4, message)

    def set_graph_preferences(self, message: anki.stats_pb2.GraphPreferences) -> anki.generic_pb2.Empty:
        
        raw_bytes = self._run_command(41, 4, message.SerializeToString())
        output = anki.generic_pb2.Empty()
        output.ParseFromString(raw_bytes)
        return output

    def clear_unused_tags_raw(self, message: bytes) -> bytes:
        return self._run_command(43, 0, message)

    def clear_unused_tags(self) -> anki.collection_pb2.OpChangesWithCount:
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(43, 0, message.SerializeToString())
        output = anki.collection_pb2.OpChangesWithCount()
        output.ParseFromString(raw_bytes)
        return output

    def all_tags_raw(self, message: bytes) -> bytes:
        return self._run_command(43, 1, message)

    def all_tags(self) -> Sequence[str]:
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(43, 1, message.SerializeToString())
        output = anki.generic_pb2.StringList()
        output.ParseFromString(raw_bytes)
        return output.vals

    def remove_tags_raw(self, message: bytes) -> bytes:
        return self._run_command(43, 2, message)

    def remove_tags(self, val: str) -> anki.collection_pb2.OpChangesWithCount:
        message = anki.generic_pb2.String(val=val)
        raw_bytes = self._run_command(43, 2, message.SerializeToString())
        output = anki.collection_pb2.OpChangesWithCount()
        output.ParseFromString(raw_bytes)
        return output

    def set_tag_collapsed_raw(self, message: bytes) -> bytes:
        return self._run_command(43, 3, message)

    def set_tag_collapsed(self, *, name: str, collapsed: bool) -> anki.collection_pb2.OpChanges:
        message = anki.tags_pb2.SetTagCollapsedRequest(name=name, collapsed=collapsed)
        raw_bytes = self._run_command(43, 3, message.SerializeToString())
        output = anki.collection_pb2.OpChanges()
        output.ParseFromString(raw_bytes)
        return output

    def tag_tree_raw(self, message: bytes) -> bytes:
        return self._run_command(43, 4, message)

    def tag_tree(self) -> anki.tags_pb2.TagTreeNode:
        message = anki.generic_pb2.Empty()
        raw_bytes = self._run_command(43, 4, message.SerializeToString())
        output = anki.tags_pb2.TagTreeNode()
        output.ParseFromString(raw_bytes)
        return output

    def reparent_tags_raw(self, message: bytes) -> bytes:
        return self._run_command(43, 5, message)

    def reparent_tags(self, *, tags: Iterable[str], new_parent: str) -> anki.collection_pb2.OpChangesWithCount:
        message = anki.tags_pb2.ReparentTagsRequest(tags=tags, new_parent=new_parent)
        raw_bytes = self._run_command(43, 5, message.SerializeToString())
        output = anki.collection_pb2.OpChangesWithCount()
        output.ParseFromString(raw_bytes)
        return output

    def rename_tags_raw(self, message: bytes) -> bytes:
        return self._run_command(43, 6, message)

    def rename_tags(self, *, current_prefix: str, new_prefix: str) -> anki.collection_pb2.OpChangesWithCount:
        message = anki.tags_pb2.RenameTagsRequest(current_prefix=current_prefix, new_prefix=new_prefix)
        raw_bytes = self._run_command(43, 6, message.SerializeToString())
        output = anki.collection_pb2.OpChangesWithCount()
        output.ParseFromString(raw_bytes)
        return output

    def add_note_tags_raw(self, message: bytes) -> bytes:
        return self._run_command(43, 7, message)

    def add_note_tags(self, *, note_ids: Iterable[int], tags: str) -> anki.collection_pb2.OpChangesWithCount:
        message = anki.tags_pb2.NoteIdsAndTagsRequest(note_ids=note_ids, tags=tags)
        raw_bytes = self._run_command(43, 7, message.SerializeToString())
        output = anki.collection_pb2.OpChangesWithCount()
        output.ParseFromString(raw_bytes)
        return output

    def remove_note_tags_raw(self, message: bytes) -> bytes:
        return self._run_command(43, 8, message)

    def remove_note_tags(self, *, note_ids: Iterable[int], tags: str) -> anki.collection_pb2.OpChangesWithCount:
        message = anki.tags_pb2.NoteIdsAndTagsRequest(note_ids=note_ids, tags=tags)
        raw_bytes = self._run_command(43, 8, message.SerializeToString())
        output = anki.collection_pb2.OpChangesWithCount()
        output.ParseFromString(raw_bytes)
        return output

    def find_and_replace_tag_raw(self, message: bytes) -> bytes:
        return self._run_command(43, 9, message)

    def find_and_replace_tag(self, *, note_ids: Iterable[int], search: str, replacement: str, regex: bool, match_case: bool) -> anki.collection_pb2.OpChangesWithCount:
        message = anki.tags_pb2.FindAndReplaceTagRequest(note_ids=note_ids, search=search, replacement=replacement, regex=regex, match_case=match_case)
        raw_bytes = self._run_command(43, 9, message.SerializeToString())
        output = anki.collection_pb2.OpChangesWithCount()
        output.ParseFromString(raw_bytes)
        return output

    def complete_tag_raw(self, message: bytes) -> bytes:
        return self._run_command(43, 10, message)

    def complete_tag(self, *, input: str, match_limit: int) -> Sequence[str]:
        message = anki.tags_pb2.CompleteTagRequest(input=input, match_limit=match_limit)
        raw_bytes = self._run_command(43, 10, message.SerializeToString())
        output = anki.tags_pb2.CompleteTagResponse()
        output.ParseFromString(raw_bytes)
        return output.tags

